Создание нового WindowsFormsSynchronizationContext - PullRequest
1 голос
/ 17 февраля 2011

У меня есть асинхронный метод в одноэлементном классе, который должен вызывать событие в потоке пользовательского интерфейса, потому что большинство людей, подписанных на это событие, являются элементами управления, но вызывающий метод не является элементом управления. Поскольку вызывающий элемент не всегда является элементом управления, я не могу передать его Invoke дальше обратно в поток пользовательского интерфейса, поэтому вместо этого я использую AsyncOperation / SynchronizationContext, чтобы получить текущий контекст потока перед запуском фонового потока, а затем в фоновом потоке. Я звоню Post, вроде как ...

public void AsyncMethod()
{
    AsyncOperation ao = AsyncOperationManager.CreateOperation(null);
    // or SynchronizationContext ctx = WindowsFormsSynchronizationContext.Current;

    ThreadPool.QueueUserWorkItem(delegate(objact state)
    {
        //do stuff
        ao.Post(delegate(object state2)
        {
            // fire event
        }, null);
    }, null);
}

Проблема в том, что AsyncOperation иногда дает мне новый контекст, или WindowsFormsSynchronizationContext имеет значение null. Я нашел кого-то еще, у кого была такая же проблема, и я думаю, что она связана с выпадающими пунктами меню, создающими элементы управления, которые будут происходить в событиях. В любом случае, мой вопрос: если WindowsFormsSynchronizationContext имеет значение null, могу ли я создать новый для вызова Post, и будет ли этот новый контекст контекста пользовательского интерфейса или контекст потока, в котором он был создан?

1 Ответ

1 голос
/ 17 февраля 2011

Если это одноэлементное приложение в пользовательском интерфейсе, я бы рекомендовал сохранить закрытый элемент типа Control, созданный в потоке пользовательского интерфейса, и использовать его для всех ваших вызовов:

  1. . Вы можететребовать, чтобы метод "initialize" вызывался из потока пользовательского интерфейса (скажем, прямо перед Application.Run) и создавал для вас синхронизирующий элемент управления там
  2. Или вы можете создать элемент управления синхронизацией при первом обращении к синглтону, либо проверивесли текущий поток выполняет цикл обработки сообщений (с Application.MessageLoop) и если не вызывает создание элемента управления на одном из Application.OpenForms.

Первый способ более детерминирован и поэтому рекомендуется.

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