Serve Laurijssen
Serve Laurijssen

Reputation: 9733

Callbacks on SynchronizationContext

Trying to wrap my head around why a windows Form implementing a callback is not working.

What I'm trying to do:

Having UseSynchronizationContext on false and calling Invoke on the GUI members works fine:

[CallbackBehavior(UseSynchronizationContext = false)]
public class DeliveryClient : System.Windows.Forms.Form, ICallback
{        
        public void ServiceCallback(string system, string state, string extraInfo)
        {
            if (state == "start")
            {
                Invoke((MethodInvoker)delegate { picBox.Visible = true; });
            }
            else
            {
                Invoke((MethodInvoker)delegate { picBox.Visible = false; });
            }
        }
}

But UseSynchronizationContext = true and directly calling the members does not:

[CallbackBehavior(UseSynchronizationContext = true)]
public class DeliveryClient : System.Windows.Forms.Form, ICallback
{        
        public void ServiceCallback(string system, string state, string extraInfo)
        {
            if (state == "start")
            {
                picBox.Visible = true;
            }
            else
            {
                picBox.Visible = false;
            }
        }

Neither does using SyynchronizationContext literally

SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);

Should the second and third version also work? The callback is called OneWay so the service continues after callback.

Upvotes: 1

Views: 568

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70652

Is your Form class really the implementation of your WCF service client callback, as WCF knows it (i.e. not just something you delegate to from the WCF client)? If not, then you've put the [CallbackBehavior] attribute in the wrong place. As the documentation states:

The CallbackBehaviorAttribute must be applied to the class that implements the callback contract

If it is the implementation of your client callback, then without a good Minimal, Complete, and Verifiable code example I'm afraid I wouldn't be able to say why the attribute isn't having the expected effect. But I would be able to say that, if that is indeed the case, your code is designed poorly. Combining your UI with your service client callback implementation violates a number of OOP principles for healthy code, but most importantly the Separation of Concerns principle.

As far as this goes:

SynchronizationContext.Current.Send(_=> picBox.Visible = true, null);

That's not how you should use SynchronizationContext. The Current property returns the context for the currently running thread. By the time you need to call Send(), it's too late to retrieve the context. You need to store SynchronizationContext.Current when you create your object, in the thread where you want delegates invoked by Send() to be executed (and of course, that thread has to have a useful context, such as found in the main UI thread of a Winforms program).

If the above does not give you enough information to get your code working, please improve the question by providing a good MCVE that reliably reproduces the problem.

Upvotes: 2

Related Questions