首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按顺序安排任务

按顺序安排任务
EN

Stack Overflow用户
提问于 2014-03-31 12:57:30
回答 2查看 730关注 0票数 1

我的任务如下:

  1. 任务taskInput将数据发送到inputQueue
  2. 任务taskOutput从inputQueue到outputQueue获取数据
  3. 使用来自outputQueue的数据的并行任务

我想以以下条件运行这些任务:

先运行taskInput,然后运行taskOutput,最后运行消费者。

相应的代码:

代码语言:javascript
复制
            // 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:

代码语言:javascript
复制
    BlockingCollection<Messages> InputQueue = new BlockingCollection<Messages>();
    BlockingCollection<Messages> OutputQueue = new BlockingCollection<Messages>();

我的问题:

  1. 安排任务。我想我们可以使用Task.ContinueWith方法bot不确定如何将其应用于Consumer
  2. 我不确定它是否线程安全,因为在运行inputQueue时,可能会将新项添加到Consumer中。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-31 13:56:09

您可以尝试启动第一个任务(taskInput),当它完成时,继续第二个任务(taskOutput),除非有必要并行工作。在这种情况下,您必须分别启动,因为您已经在这样做。

代码语言:javascript
复制
Task.Run(() => AddingItemToInputQueue())
            .ContinueWith(task => AddItemToOutputQueue());

同时,启动用于使用来自outputQueue的数据的任务

代码语言:javascript
复制
// 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);

或者你可以试试这样的方法:

代码语言:javascript
复制
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.StartNewTask.Run 这里的更多信息。

票数 1
EN

Stack Overflow用户

发布于 2014-04-01 08:28:39

使用async-await,您可以这样编写它:

代码语言:javascript
复制
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);
}

但是,由于您需要用AddingItemToInputQueueAddItemToOutputQueue封装Task以使它们是异步的,所以您只是增加了开销。Consumer也是如此。

你最好这样做:

代码语言:javascript
复制
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));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22762153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档