У каждого потока WinRT/Windows Core есть Диспетчер?

Мы предоставляем библиотеку, которая должна запускать код в собственных пользовательских потоках. После этого я хочу, чтобы эти потоки вызывали обратные вызовы (обработчики событий) через Dispatcher (System.Windows.Threading.Dispatcher). Пользователь библиотеки должен использовать Dispatcher для отправки обработки события.

Мы могли бы просто отправить на CoreApplication.MainView.CoreWindow.Dispatcher но не все программы (например, приложения IoT Core для Windows 10) предоставляют пользовательский интерфейс, и поэтому им не хватает главного окна.

Может ли пользователь просто обратиться к System.Windows.Threading.Dispatcher.CurrentDispatcher, чтобы получить поток Dispatcher? Или не все темы могут иметь Dispatcher?

Изменить: Вот больше контекста для этого вопроса. Надеюсь, это облегчает понимание вопроса: https://github.com/getsenic/nuimo-windows/issues/2

2 ответа

Во-первых, я не уверен, что вы должны выполнять обработчики событий в потоке пользовательского интерфейса, потому что только клиент знает, нужен ли ему доступ к элементам пользовательского интерфейса.

За секунду до вызова CoreApplication.MainView собственность, которую вы можете проверить CoreApplication.Views.Count > 0 (Я не совсем уверен, что это будет работать, потому что в настоящее время у меня нет устройства для его тестирования).

А также вы можете решить эту проблему другим способом: в конструкторе вашего объекта сохраните SynchronizationContext исполняемого потока, а затем используйте его для вызова событий. Это будет работать, если ваш объект создается из потока пользовательского интерфейса (в большинстве случаев это правда). Таким образом, вы можете полностью отказаться от Dispatcher.

public class NotifierExample
{
    private readonly SynchronizationContext _synchronizationContext;


    public event EventHandler SomethingHappened;


    public NotifierExample()
    {
        _synchronizationContext = SynchronizationContext.Current;
    }


    public void Do()
    {
        Task.Factory.StartNew(() =>
        {
            //do something
            OnSomethingHappened();
        });
    }


    private void OnSomethingHappened()
    {
        if (_synchronizationContext != null)
        {
            _synchronizationContext.Post(o => RaiseSomethingHappened(), null);
        }
        else
        {
            RaiseSomethingHappened();
        }
    }

    private void RaiseSomethingHappened()
    {
        var somethingHappened = SomethingHappened;
        somethingHappened?.Invoke(this, EventArgs.Empty);
    }
}

Или не все темы могут иметь Dispatcher?

Потоки диспетчера всегда связаны с потоками пользовательского интерфейса. Приложение безголового режима IoT не имеет пользовательского интерфейса, поэтому у него нет потока Dispatcher.

Может ли пользователь просто обратиться к System.Windows.Threading.Dispatcher.CurrentDispatcher, чтобы получить Dispatcher своего потока

System.Windows.Threading.Dispatcher.CurrentDispatcher поддерживается только в устаревшей платформе.NET. Альтернативой UWP является CoreApplication.MainView.CoreWindow.Dispatcher, как вы указали.

Если вы хотите выполнять асинхронные обратные вызовы в режиме без головы (без графического интерфейса пользователя), вы, вероятно, можете обратиться к параллельной библиотеке задач (TPL), ContinueWhenAll ContinueWhenAny и т. Д. API... может вполне удовлетворить ваши потребности. См. https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.aspx.

Другие вопросы по тегам