簡體   English   中英

非UI線程上的WPF Dispatcher

[英]WPF Dispatcher on non-UI thread

根據MSDN, Dispatcher 提供了用於管理線程工作項隊列的服務。

一個簡單的問題。 我想為此使用Dispatcher :作為工作項的隊列(通過Dispatcher.BeginInvoke發布),我的后台線程將以串行方式提供。

我不想將此線程設為STA線程,也不需要在其上注入Windows消息。 這個帖子上沒有UI。

這是使用Dispatcher的合法方式嗎?

這是使用Dispatcher的合法方式嗎?

可以 將輔助線程與Dispatcher一起使用 ,但這種情況並不常見。 通常這樣做是為了使UI的不同部分在不同的UI線程上運行。 調度程序線程將處理Windows消息,並且必須是STA。 同樣,從技術上講,處理並不是嚴格意義上的FIFO,因為已調度的項目將按優先級排隊。

也就是說,即使不是沒有UI也不打算使用它,您也可以那樣使用它。

備擇方案:

1) AsyncContextThread是一個帶有AsyncEx NuGet庫工作隊列的簡單線程:

private readonly AsyncContextThread _thread = new AsyncContextThread();
...
_thread.Factory.StartNew(() => { ... });

AsyncContextThread類型為其運行的代碼提供SynchronizationContext ,因此默認情況下async延續將在同一線程上恢復。

2)如果請求是按順序處理的,並且實際上它們運行的​​是哪個線程並不重要,那么您可以使用任務調度程序來指示線程池一次運行一個請求,如下所示:

private readonly TaskFactory _factory = new TaskFactory(
    new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler);
_factory.StartNew(() => { ... });

簡短回答:

如果您實際上需要使用Dispatcher運行時組件(例如System.Windows.Media.Imaging),那么我為您提供了一個答案。 如果您不使用Dispatcher運行時組件,那么甚至不要考慮使用Dispatcher運行時。 請改用任務並行庫(TPL)。

答案很長:

我已經在大量生產服務中構建並使用了DispatcherTaskScheduler實現 您可以使用盡可能多的線程配置它以擁有一個池(默認為核心數),它將負責啟動這些線程,使用Dispatcher運行時初始化它們,然后排隊並將工作分派到他們。 與TPL,TPL DataFlow, SynchronizationContext樣式編程(例如async / await)等緊密配合使用。

基本用法如下所示:

Task.Factory.StartNew(() =>
{
   // Do anything you want with Dispatcher components here
},
CancellationToken.None,
TaskCreationOptions.None,
DispatcherTaskFactory.Default);

如果您配置自己的實例(例如,您想要更多的線程),則只需將DispatcherTaskFactory.Default替換為您的實例。 我的建議是不要配置比內核更多的線程(僅使用Default實例),並確保您僅嘗試在這些線程上執行Dispatcher運行時工作。

正如我提到的,我在與圖像處理相關的軟件系統的多個部分中使用了該實現,這些實現是我們業務的核心,並承受大量負載,並且事實證明,這對我們來說絕對是證明。

最后,免責聲明:Microsoft並不真正支持像這樣使用Dispatcher運行時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM