WCF回调没有按预期工作
本文关键字:工作 回调 WCF | 更新日期: 2023-09-27 18:13:58
我创建了一个WCF服务,它对WPF客户端进行回调。我只是在WPF客户端的文本框中显示进度。我首先得到的是跨线程操作无效。然后修改客户端代码,使用Invoke()
、BeginInvoke()
等方法实现。现在,客户端代码只显示值100%。实际上它应该显示0-100%的值。有解决方案吗?
wcf service的代码:
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";
}
}
}
当调用服务时,GUI线程被卡在button_click方法中。所以GUI线程不能被冻结。
有(至少)两种可行的解决方案,我对它们进行了测试:
-
将
[OperationContract(IsOneWay = true)]
同时置于服务器和回调操作 -
把
[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(); }