【问题标题】:WCF callback not working as expectedWCF 回调未按预期工作
【发布时间】:2015-09-23 04:39:04
【问题描述】:

我创建了一个 WCF 服务,它对 WPF 客户端进行回调。我只是在 WPF 客户端的文本框中显示进度。我首先得到的是跨线程操作无效。然后我修改了客户端代码,使用Invoke()和BeginInvoke()等方法实现。现在客户端代码只显示值 100%。实际上它应该显示 0-100% 的值。有什么解决办法吗?

wcf服务的代码:

namespace ReportService
{
    [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant,InstanceContextMode=InstanceContextMode.Single)]
    public class Report : IReportService
    {
        public void ProcessReport()
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(1000);
              OperationContext.Current.GetCallbackChannel<IReportCallback>().ReportProgress(i);

            }
        }
    }
}

客户端代码:

namespace Report
{
    [CallbackBehavior(UseSynchronizationContext=false)]
    public partial class Form1 : Form,ReportService.IReportServiceCallback
    {
        delegate void delSetTxt(int percentCompleted);
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            InstanceContext ic= new InstanceContext(this);
            ReportService.ReportServiceClient client = new ReportService.ReportServiceClient(ic);
            client.ProcessReport();
        }
        public void ReportProgress(int percentCompleted)
        {
           // this.Invoke(new Action(() => { this.textBox1.Text = percentCompleted.ToString(); }));
            Thread t = new Thread(() => setTxt(percentCompleted));
            t.Start();

        }
        public void setTxt(int percentCompleted)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new delSetTxt(setTxt), new object[] { percentCompleted });
                return;
            }
            this.textBox1.Text = percentCompleted.ToString() + " % complete";

        }

    }
}

【问题讨论】:

  • 您是否考虑过您的操作速度有多快?也许您的眼睛只能看到最后 100% 的值,因为所有其他之前的值都报告得太快了。此外,为了更有帮助,您应该输入您的代码:wcf 部分和 wpf 部分。否则只是我们的猜测。
  • 在 foo.cs 的第 55 行。
  • 我放慢了这个过程。它仅在 100% 后显示。
  • 也许我遗漏了一些东西,但为什么要启动一个线程? BeginInvoke,立即返回。
  • 我起初尝试不使用线程。但它显示跨线程无效错误。然后我通过添加互联网中给出的解决方案中的线程来修改代码。但没有任何效果。

标签: c# wpf wcf


【解决方案1】:

调用服务时,GUI 线程卡在 button_click 方法中。 所以不能冻结 GUI 线程。
有(至少)两种可行的解决方案,我对它们进行了测试:

  1. 把[OperationContract(IsOneWay = true)]放在服务器和回调操作上

  2. 将[OperationContract(IsOneWay = true)]放在回调操作上,不要用await/async锁定GUI线程:

    private async void button1_Click(object sender, EventArgs e)
    {  
      InstanceContext ic = new InstanceContext(this);  
      ReportServiceClient client = new ReportServiceClient(ic);  
      await client.ProcessReportAsync();  
      //client.ProcessReport();  
    }
    

祝你好运

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 2017-09-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多