是否有一个C#等同于Java的CompletionService对完成线程反应? [英] Is there a C# equivalent to Java CompletionService to react to completed threads?

查看:128
本文介绍了是否有一个C#等同于Java的CompletionService对完成线程反应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有很多关于如何等待所有工人作业完成的例子,但什么反应,因为每个工人以同样的方式作为Java的CompletionService完成?



我砍死在一起一些作品,但似乎这是脆弱的:

  INT completedWorkers = 0; 
,而(completedWorkers< workerCount)
{
INT事件ID = WaitHandle.WaitAny(eventArray);
事件[事件ID] .reset段();
completedWorkers ++;
Console.WriteLine(工人{0}完成{1}现在已经完成了。,事件ID,completedWorkers);
}
Console.WriteLine(所有线程都完成);

这依赖ManualResetEvent的实例('eventArray在我的例子),数组类似所示在微软的例子, http://msdn.microsoft.com/en-us/库/ 3dasc8as.aspx (但是他们的代码使用了WaitAll()来等待所有的工人来完成,而不是作为反应每个工人完成)。



编辑:



我已经接受了使用TPL道格拉斯的回答,但作为参考,代表们给我们这个功能开箱:

  IAsyncResult的结果= caller.BeginInvoke(
新的AsyncCallback(CallbackMethod),
上执行的线程调用{0}与返回值\{1} \)。

...

无效CallbackMethod(IAsyncResult的AR)
{
//'反应'来异步委托完成
}


解决方案

如果您使用任务并行库,您可以附加一个延续给每个任务。

  INT completedWorkers = 0; 
VAR延续= tasks.Select((任务,指数)=> task.ContinueWith(前身= GT;
{
锁(任务)//如果你想避免比赛只要求递增和写作
{
INT _index =指数之间; //避免倒闭的问题
completedWorkers ++; //如果锁被删除,替换为:Interlocked.Increment(REF completedWorkers);
Console.WriteLine(工人{0}完成{1}现在已经完成了。_index,completedWorkers);
}
}));
Task.WaitAll(continuations.ToArray());
Console.WriteLine(所有线程都完成);


There are lots of examples of how to wait for all 'worker' jobs to finish, but what about reacting as each worker completes in the same way as Java's CompletionService?

I've hacked together something that works, but this seems fragile:

int completedWorkers = 0;
while (completedWorkers < workerCount)
{
     int eventId = WaitHandle.WaitAny(eventArray);
     events[eventId].Reset();
     completedWorkers++;
     Console.WriteLine("Worker {0} has completed. {1} have now completed.", eventId, completedWorkers);
}
Console.WriteLine("All threads have finished");

This relies on an array of ManualResetEvent instances ('eventArray' in my example), similar to that shown in the Microsoft example, http://msdn.microsoft.com/en-us/library/3dasc8as.aspx (however their code uses WaitAll() to wait for all workers to finish, not reacting as each worker finishes).

Edit:

I've accepted Douglas's answer using the TPL, but for reference, Delegates give us this functionality out of the box:

IAsyncResult result = caller.BeginInvoke(
                new AsyncCallback(CallbackMethod),
                "The call executed on thread {0}, with return value \"{1}\".");

...

void CallbackMethod(IAsyncResult ar) 
{
    // 'react' to async delegates completing
}

解决方案

If you use the Task Parallel Library, you could attach a continuation to each of your tasks.

int completedWorkers = 0;
var continuations = tasks.Select((task, index) => task.ContinueWith(antecedent =>
{
    lock (tasks)   // only required if you want to avoid races between incrementing and writing
    {
        int _index = index;   // avoid closures issue
        completedWorkers++;   // if lock is removed, replace with: Interlocked.Increment(ref completedWorkers);
        Console.WriteLine("Worker {0} has completed. {1} have now completed.", _index, completedWorkers);
    }
}));
Task.WaitAll(continuations.ToArray());
Console.WriteLine("All threads have finished");

这篇关于是否有一个C#等同于Java的CompletionService对完成线程反应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆