Reputation: 863
I made a WCF service which makes a callback to a WPF client. I just show the progress in a textbox in the WPF client. What I got first is cross thread operation not valid. Then I modified the client side code and implemented using methods such as Invoke()
and BeginInvoke()
. Now the client side code shows only the value 100%. Actually it should display the values from 0-100%. Any solutions?
The code at 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);
}
}
}
}
Code at client:
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";
}
}
}
Upvotes: 1
Views: 346
Reputation: 4913
When the call is made to the service, the GUI thread is stuck in the button_click method.
So the GUI thread must not be frozen.
There are (at least) two solutions that work, I tested them :
Put [OperationContract(IsOneWay = true)]
both on the server and the callback operation
Put [OperationContract(IsOneWay = true)]
on the callback operation and don't lock GUI thread with await/async
:
private async void button1_Click(object sender, EventArgs e)
{
InstanceContext ic = new InstanceContext(this);
ReportServiceClient client = new ReportServiceClient(ic);
await client.ProcessReportAsync();
//client.ProcessReport();
}
Good luck
Upvotes: 2