Juan
Juan

Reputation: 15715

Run service operation on a different thread than the service thread

I'm working on a WinForms application that will contain a WebBrowser and will act as a service for another process. I'd like to implement a NavigateAndWait method, but apparently, when I invoke my service's (my WinForms application) methods from the client, this methods run in the same thread or somehow in synchronization with the service's UI thread. This is what I have so far:

Service:

public class Browser : IBrowser
{
    private bool _Navigating = false;

    public bool Navigating
    {
        get { return _Navigating; }
    }

    public Browser()
    {
        ServiceForm.Instance.webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
    }

    void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if(e.Url == ServiceForm.Instance.webBrowser1.Url) _Navigating = false;
    }

    public void Navigate(string url)
    {
        _Navigating = true;
        ServiceForm.Instance.webBrowser1.Navigate(url);
    }
}

Client:

    private void button1_Click(object sender, EventArgs e)
    {
        EndpointAddress endpointAddress = new EndpointAddress("net.pipe://localhost/PipeReverse/PipeReverse");
        NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding();
        ChannelFactory<IBrowser> pipeFactory = new ChannelFactory<IBrowser>(pipeBinding, endpointAddress);
        IBrowser browser = pipeFactory.CreateChannel();
        browser.Navigate("http://www.google.com");
        while (browser.Navigating) { }
        MessageBox.Show("done!");
    }

This works OK other than my client will freeze for a little while (literally!). I could easily run button1_Click on another thread in my client, but what I'd really want to do is implement my NavigateAndWait (which would basically be the last three lines of code in the button1_Click method) in my service. But I've tried this and it never returns, apparently because the DocumentComplete event handler never gets called because I'm inside the while loop running in the service's UI thread.

So my question is how can I tell WCF to run my service's operation on a thread other than the UI thread so I can do my while loop in that other thread?

Upvotes: 2

Views: 562

Answers (1)

carlosfigueira
carlosfigueira

Reputation: 87218

You need to use the UseSynchronizationContext = false option in the [ServiceBehavior] attribute in your service. That will tell WCF not to enforce the posting of all requests to the thread where it was created (in your case, the UI thread). That attribute would go in the service class (not the interface).

Upvotes: 2

Related Questions