سؤال

According to MSDN, Dispatcher provides services for managing the queue of work items for a thread.

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.

I don't want to make this thread an STA thread and I don't need to pump Windows messages on it. There will be no UI on this thread.

Is it a legitimate way of using Dispatcher?

هل كانت مفيدة؟

المحلول 2

Short answer:

If you need to actually do work with Dispatcher runtime components, such as System.Windows.Media.Imaging, then I have an answer for you. If you're not using Dispatcher runtime components then don't even consider using the Dispatcher runtime. Use the Task Parallel Library (TPL) instead.

Long answer:

I've built and use this DispatcherTaskScheduler implementation in high volume production services. 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. Works with great with TPL, TPL DataFlow, SynchronizationContext style programming (e.g. async/await), etc.

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 (e.g. you want more threads) then just replace DispatcherTaskFactory.Default with your instance instead. 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.

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.

نصائح أخرى

Is it a legitimate way of using Dispatcher?

You could use a secondary thread with a Dispatcher, but it's rather uncommon. This is usually done so that different parts of the UI run on different UI threads. A dispatcher thread will process Windows messages, and must be STA. Also, technically speaking the processing isn't strictly FIFO since dispatched items are queued with a priority.

That said, even though it wasn't designed to be used without a UI, you could use it that way.

Alternatives:

1) AsyncContextThread is a simple thread with a work queue from my AsyncEx NuGet library:

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.

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:

private readonly TaskFactory _factory = new TaskFactory(
    new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler);
_factory.StartNew(() => { ... });
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top