Запустите операцию службы в потоке, отличном от потока службы - PullRequest
2 голосов
/ 22 октября 2011

Я работаю над приложением WinForms, которое будет содержать WebBrowser и будет действовать как служба для другого процесса. Я хотел бы реализовать метод NavigateAndWait, но, очевидно, когда я вызываю методы моей службы (моего приложения WinForms) из клиента, эти методы выполняются в том же потоке или как-то синхронно с потоком пользовательского интерфейса службы. Это то, что я до сих пор:

Услуги:

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 никогда не вызывается, потому что я нахожусь внутри цикла while, работающего в потоке пользовательского интерфейса службы.

Таким образом, мой вопрос заключается в том, как я могу сказать WCF запустить операцию моей службы в потоке, отличном от потока пользовательского интерфейса, чтобы я мог выполнить цикл while в этом другом потоке?

1 Ответ

2 голосов
/ 22 октября 2011

Вам необходимо использовать опцию UseSynchronizationContext = false в атрибуте [ServiceBehavior] в вашем сервисе.Это скажет WCF не принудительно отправлять все запросы в поток, где он был создан (в вашем случае, поток пользовательского интерфейса).Этот атрибут будет идти в службу класс (не интерфейс).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...