[英]WPF Dispatcher on non-UI thread
According to MSDN, Dispatcher
provides services for managing the queue of work items for a thread. 根据MSDN,
Dispatcher
提供了用于管理线程工作项队列的服务。
A simple question. 一个简单的问题。 I want to use
Dispatcher
just for that: as a queue of work items (posted via Dispatcher.BeginInvoke
) which my background thread will serve in a serial manner. 我想为此使用
Dispatcher
:作为工作项的队列(通过Dispatcher.BeginInvoke
发布),我的后台线程将以串行方式提供。
I don't want to make this thread an STA thread and I don't need to pump Windows messages on it. 我不想将此线程设为STA线程,也不需要在其上注入Windows消息。 There will be no UI on this thread.
这个帖子上没有UI。
Is it a legitimate way of using Dispatcher
? 这是使用
Dispatcher
的合法方式吗?
Is it a legitimate way of using Dispatcher?
这是使用Dispatcher的合法方式吗?
You could use a secondary thread with a Dispatcher
, but it's rather uncommon. 您可以 将辅助线程与
Dispatcher
一起使用 ,但这种情况并不常见。 This is usually done so that different parts of the UI run on different UI threads. 通常这样做是为了使UI的不同部分在不同的UI线程上运行。 A dispatcher thread will process Windows messages, and must be STA.
调度程序线程将处理Windows消息,并且必须是STA。 Also, technically speaking the processing isn't strictly FIFO since dispatched items are queued with a priority.
同样,从技术上讲,处理并不是严格意义上的FIFO,因为已调度的项目将按优先级排队。
That said, even though it wasn't designed to be used without a UI, you could use it that way. 也就是说,即使不是没有UI也不打算使用它,您也可以那样使用它。
Alternatives: 备择方案:
1) AsyncContextThread
is a simple thread with a work queue from my AsyncEx NuGet library: 1)
AsyncContextThread
是一个带有AsyncEx NuGet库工作队列的简单线程:
private readonly AsyncContextThread _thread = new AsyncContextThread();
...
_thread.Factory.StartNew(() => { ... });
The AsyncContextThread
type provides a SynchronizationContext
for the code it runs, so async
continuations will resume on the same thread by default. AsyncContextThread
类型为其运行的代码提供SynchronizationContext
,因此默认情况下async
延续将在同一线程上恢复。
2) If it only matters that the requests are processed serially , and doesn't actually matter which thread they run on, then you can use a task scheduler to instruct the thread pool to run your requests one at a time, as such: 2)如果请求是按顺序处理的,并且实际上它们运行的是哪个线程并不重要,那么您可以使用任务调度程序来指示线程池一次运行一个请求,如下所示:
private readonly TaskFactory _factory = new TaskFactory(
new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler);
_factory.StartNew(() => { ... });
If you need to actually do work with Dispatcher
runtime components, such as System.Windows.Media.Imaging, then I have an answer for you. 如果您实际上需要使用
Dispatcher
运行时组件(例如System.Windows.Media.Imaging),那么我为您提供了一个答案。 If you're not using Dispatcher
runtime components then don't even consider using the Dispatcher
runtime. 如果您不使用
Dispatcher
运行时组件,那么甚至不要考虑使用Dispatcher
运行时。 Use the Task Parallel Library (TPL) instead. 请改用任务并行库(TPL)。
I've built and use this DispatcherTaskScheduler
implementation in high volume production services. 我已经在大量生产服务中构建并使用了此
DispatcherTaskScheduler
实现 。 You can configure it with as many threads as you'd like it to have a pool of (default is number of cores) and it will take care of spinning up those threads, initializing them with the Dispatcher
runtime and then queuing and dispatching work to them. 您可以使用尽可能多的线程配置它以拥有一个池(默认为核心数),它将负责启动这些线程,使用
Dispatcher
运行时初始化它们,然后排队并将工作分派到他们。 Works with great with TPL, TPL DataFlow, SynchronizationContext
style programming (eg async/await), etc. 与TPL,TPL DataFlow,
SynchronizationContext
样式编程(例如async / await)等紧密配合使用。
Basic usage looks something like this: 基本用法如下所示:
Task.Factory.StartNew(() =>
{
// Do anything you want with Dispatcher components here
},
CancellationToken.None,
TaskCreationOptions.None,
DispatcherTaskFactory.Default);
If you configure your own instance (eg you want more threads) then just replace DispatcherTaskFactory.Default
with your instance instead. 如果您配置自己的实例(例如,您想要更多的线程),则只需将
DispatcherTaskFactory.Default
替换为您的实例。 My advice is to not configure more threads than cores (just use the Default
instance) and make sure you try to only do Dispatcher
runtime work on these threads. 我的建议是不要配置比内核更多的线程(仅使用
Default
实例),并确保您仅尝试在这些线程上执行Dispatcher
运行时工作。
As I mentioned, I use this implementation in several parts of our software system related to image processing that are core to our business and endure high volume loads and it's proven absolutely bullet proof for us. 正如我提到的,我在与图像处理相关的软件系统的多个部分中使用了该实现,这些实现是我们业务的核心,并承受大量负载,并且事实证明,这对我们来说绝对是证明。
Finally, the disclaimer: Microsoft doesn't really support the Dispatcher
runtime being used like this. 最后,免责声明:Microsoft并不真正支持像这样使用
Dispatcher
运行时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.