在与服务线程不同的线程上运行服务操作

时间:2011-10-21 23:21:32

标签: c# .net winforms multithreading wcf

我正在开发一个包含WebBrowser的WinForms应用程序,并将作为另一个进程的服务。我想实现一个NavigateAndWait方法,但显然,当我从客户端调用我的服务(我的WinForms应用程序)方法时,这些方法在同一个线程中运行或以某种方式与服务的UI线程同步。这就是我到目前为止所做的:

服务:

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);
    }
}

客户端:

    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!");
    }

除了我的客户端会冻结一段时间(字面意思!)之外,这项工作正常。我可以在我的客户端的另一个线程上轻松运行button1_Click,但我真正想做的是实现我的NavigateAndWait(这基本上是{{1}中的最后三行代码我的服务中的方法)。但我已经尝试了这个并且它永远不会返回,显然是因为button1_Click事件处理程序永远不会被调用,因为我在服务的UI线程中运行的DocumentComplete循环内。

所以我的问题是如何告诉WCF在UI线程以外的线程上运行我的服务操作,以便我可以在其他线程中执行我的while循环?

1 个答案:

答案 0 :(得分:2)

您需要使用服务中UseSynchronizationContext = false属性中的[ServiceBehavior]选项。这将告诉WCF不强制将所有请求发布到创建它的线程(在您的情况下,UI线程)。该属性将在服务(不是界面)中进行。