Noxious Reptile
Noxious Reptile

Reputation: 863

WCF callback not working as expected

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

Answers (1)

Emmanuel DURIN
Emmanuel DURIN

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 :

  1. Put [OperationContract(IsOneWay = true)] both on the server and the callback operation

  2. 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

Related Questions