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

本文关键字:线程 服务 运行 操作 | 更新日期: 2023-09-27 18:12:06

我正在开发一个WinForms应用程序,它将包含一个WebBrowser,并将作为另一个进程的服务。我想实现一个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(基本上是button1_Click方法中的最后三行代码)。但是我已经尝试过了,它永远不会返回,显然是因为DocumentComplete事件处理程序从未被调用,因为我在服务的UI线程中运行的while循环。

所以我的问题是我怎么能告诉WCF运行我的服务的操作在一个线程上而不是UI线程,所以我可以做我的while循环在那个其他线程?

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

您需要在您的服务的[ServiceBehavior]属性中使用UseSynchronizationContext = false选项。这将告诉WCF不要强制将所有请求发送到创建它的线程(在您的示例中,是UI线程)。该属性将放在服务中(而不是接口)。