Zan*_*oni 22 c# queue multithreading
有没有更好的方法在执行另一个进程之前等待排队的线程?
目前我在做:
this.workerLocker = new object(); // Global variable
this.RunningWorkers = arrayStrings.Length; // Global variable
// Initiate process
foreach (string someString in arrayStrings)
{
ThreadPool.QueueUserWorkItem(this.DoSomething, someString);
Thread.Sleep(100);
}
// Waiting execution for all queued threads
lock (this.workerLocker) // Global variable (object)
{
while (this.RunningWorkers > 0)
{
Monitor.Wait(this.workerLocker);
}
}
// Do anything else
Console.WriteLine("END");
Run Code Online (Sandbox Code Playgroud)
// Method DoSomething() definition
public void DoSomething(object data)
{
// Do a slow process...
.
.
.
lock (this.workerLocker)
{
this.RunningWorkers--;
Monitor.Pulse(this.workerLocker);
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*fen 14
您可能想要查看AutoResetEvent和ManualResetEvent.
这些都是针对这种情况的(在做"某事"之前等待ThreadPool线程完成).
你会做这样的事情:
static void Main(string[] args)
{
List<ManualResetEvent> resetEvents = new List<ManualResetEvent>();
foreach (var x in Enumerable.Range(1, WORKER_COUNT))
{
ManualResetEvent resetEvent = new ManualResetEvent();
ThreadPool.QueueUserWorkItem(DoSomething, resetEvent);
resetEvents.Add(resetEvent);
}
// wait for all ManualResetEvents
WaitHandle.WaitAll(resetEvents.ToArray()); // You probably want to use an array instead of a List, a list was just easier for the example :-)
}
public static void DoSomething(object data)
{
ManualResetEvent resetEvent = data as ManualResetEvent;
// Do something
resetEvent.Set();
}
Run Code Online (Sandbox Code Playgroud)
编辑:忘记提及你可以等待单个线程,任何线程等等.另外,根据您的情况,AutoResetEvent可以简化一些事情,因为它(顾名思义)可以自动发出事件信号:-)
Mar*_*ell 13
怎么样Fork
和Join
使用只是Monitor
;-p
Forker p = new Forker();
foreach (var obj in collection)
{
var tmp = obj;
p.Fork(delegate { DoSomeWork(tmp); });
}
p.Join();
Run Code Online (Sandbox Code Playgroud)
这个早期答案中显示的完整代码.
或者对于上限大小的生产者/消费者队列(线程安全等),这里.