我的任务如下:
我想用以下条件运行任务:
首先运行taskInput,taskOutput,最后运行Consumer。
相应的代码:
// Get data to inputQueue
Task taskInput = new Task(()=>AddingItemToInputQueue());
taskInput.Start();
// Grab data from inputQueue to outputQueue.
Task taskOutput = new Task(() => AddItemToOutputQueue());
taskOutput.Start();
// Parallel tasks for consume data from outputQueue
int threadCount = n;
Task[] workers = new Task[threadCount];
for (int i = 0; i < threadCount; ++i)
{
Task task=Task.Run(()=>Consumer(i));
workers[i] = task;
}
Task.WaitAll(workers);
关于inputQueue和outputQueue:
BlockingCollection<Messages> InputQueue = new BlockingCollection<Messages>();
BlockingCollection<Messages> OutputQueue = new BlockingCollection<Messages>();
我的问题:
Consumer
。Consumer
时可能会将新项目添加到inputQueue。答案 0 :(得分:1)
您可以尝试启动第一个任务(taskInput
),当它完成后,继续执行第二个任务(taskOutput
),除非必须并行工作。在这种情况下,您必须单独启动,因为您已经在做。
Task.Run(() => AddingItemToInputQueue())
.ContinueWith(task => AddItemToOutputQueue());
并行地,从outputQueue
// Parallel tasks for consume data from outputQueue
int threadCount = n;
Task[] workers = new Task[threadCount];
for (int i = 0; i < threadCount; ++i)
{
Task task = Task.Run(() => Consumer(i));
workers[i] = task;
}
Task.WaitAll(workers);
或者你可以试试这样的事情:
Task.Run(() => AddingItemToInputQueue())
.ContinueWith(x => AddItemToOutputQueue())
.ContinueWith(t =>
{
int threadCount = n;
Task[] workers = new Task[threadCount];
for (int i = 0; i < threadCount; ++i)
{
Task task = Task.Run(() => Consumer(i));
workers[i] = task;
}
Task.WaitAll(workers);
});
在这种情况下,它会按您的意愿运行:首先taskInput
,然后是taskOutput
,最后是Consumer
。
BlockingCollection是线程安全的,因此您可以在多任务中添加和删除数据,它将在必要时管理自身阻止。
您可以查看有关Task.Factory.StartNew
和Task.Run
here
答案 1 :(得分:0)
使用async-await
,您可以这样写:
async Task DoStuffAsync()
{
// Get data to inputQueue
await Task.Run(()=>AddingItemToInputQueue());
// Grab data from inputQueue to outputQueue.
await Task.Run(() => AddItemToOutputQueue());
// Parallel tasks for consume data from outputQueue
int threadCount = n;
Task[] workers = new Task[threadCount];
for (int i = 0; i < threadCount; ++i)
{
Task task=Task.Run(()=>Consumer(i));
workers[i] = task;
}
await Task.WhenAll(workers);
}
但是,由于您需要将AddingItemToInputQueue
和AddItemToOutputQueue
与Task
包装在一起以使它们异步,因此您只需增加开销。同样适用于Consumer
。
你不妨这样做:
void DoStuff()
{
// Get data to inputQueue
AddingItemToInputQueue();
// Grab data from inputQueue to outputQueue.
AddItemToOutputQueue();
// Parallel tasks for consume data from outputQueue
int threadCount = n;
Parallel.For(0, n, i => Consumer(i));
}