[英]In .Net/C# is there a way to either wait for or get notified when all my worker threads have completed processing?
I've got a .Net C# application where I'm attempting to spawn multiple threads. 我有一个.Net C#应用程序,试图在其中生成多个线程。 The application is for performance testing and is a simple console app.
该应用程序用于性能测试,是一个简单的控制台应用程序。 The piece for spawning threads works fine.
产生线程的部分工作正常。
What I'm looking for is the correct mechanism fo either being notified when all the threads complete execution, or waiting within my application for all the threads to complete. 我正在寻找的是正确的机制,要么在所有线程完成执行时收到通知,要么在我的应用程序中等待所有线程完成。 At the point I will print out the summary of the results.
此时,我将打印出结果摘要。
String testName = "foo";
String fullTestName;
// Iterate and create threads
for (int index = 0; index < numberOfThreads; index++)
{
fullTestName = String.Format("{0}Thread{1}", testName, index);
Thread thread = new Thread(() => PerformanceTest(fullTestName, index, numberOfRows, testToRun));
thread.IsBackground = true;
thread.Name = fullTestName;
thread.Start();
}
void PerformanceTest(String testName, int iterationNumber, long numberOfRows)
{
// Insert a bunch of rows into DB
}
I've looked at using RegisterWaitForSingleObject(), but could not figure out how to use it with my scenario. 我已经看过使用RegisterWaitForSingleObject(),但无法弄清楚如何在我的方案中使用它。
You can use Task
instead of Thread
. 您可以使用
Task
而不是Thread
。 It gives you higher level of abstraction over parallel operations and with that a nice library of synchronization methods. 它为您提供了比并行操作更高的抽象级别,以及一个不错的同步方法库。 For example you can use the following to wait for all Tasks to finish.
例如,您可以使用以下命令等待所有任务完成。
IEnumerable<Task> BeginParallelTests(string fullTestName, int numberOfThreads)
{
for(var index = 0; index < numberOfThreads; index++)
{
yield return Task.Factory.StartNew(
() => PerformanceTest(fullTestName, index, numberOfRows));
}
}
And then in your main method you can use just: 然后,在您的主要方法中,您可以只使用:
Task.WaitAll(BeginParallelTests(testName, numberOfThreads));
(Maybe you'll have to use something like ToArray()
to force the enumeration of the the BeginParallelTest
method) (也许您必须使用类似
ToArray()
来强制枚举BeginParallelTest
方法)
Try using Tasks instead of threads. 尝试使用任务而不是线程。
class Program
{
static Random random = new Random();
static void Main(string[] args)
{
TaskFactory taskfactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var task = taskfactory.StartNew(() => { DoWork("Thread " + i); });
Console.WriteLine(string.Format("Started thread {0}", i));
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
static void DoWork(string threadname)
{
int sleeptime = random.Next(10) * 1000;
Console.WriteLine(string.Format("Thread {0} sleeping {1}ms", threadname, sleeptime));
Thread.Sleep(sleeptime);
}
}
What I'm looking for is the correct mechanism fo either being notified when all the threads complete execution, or waiting within my application for all the threads to complete.
我正在寻找的是正确的机制,要么在所有线程完成执行时收到通知,要么在我的应用程序中等待所有线程完成。
The simplest approach is just to keep track of the threads (use an array) and then call Thread.Join
on each thread in turn: 最简单的方法是跟踪线程(使用数组),然后依次在每个线程上调用
Thread.Join
:
Thread[] threads = new Thread[numberOfThreads];
for (int index = 0; index < numberOfThreads; index++)
{
string fullTestName = String.Format("{0}Thread{1}", testName, index);
Thread thread = new Thread
(() => PerformanceTest(fullTestName, index, numberOfRows, testToRun));
thread.IsBackground = true;
thread.Name = fullTestName;
thread.Start();
threads[index] = thread;
}
// Wait for everything to finish
foreach (Thread thread in threads)
{
thread.Join();
}
Using the Task Parallel Library would be another alternative, but then you may well not have many threads running at a time - it may well perform better that way, but if you're trying to measure what happens with a specific number of threads, you need to really start them all yourself. 使用任务并行库是另一种选择,但是您一次可能没有很多线程在运行-这样可能会更好地执行,但是如果您要衡量特定数量的线程会发生什么,您可以需要真正地自己启动它们。
Another suggestion would be to step up a level of abstraction with either PLinq or the new asynch keywords. 另一个建议是使用PLinq或新的asynch关键字提高抽象水平。
Here is a PLinq example that abstracts threading away from the developer to the framework. 这是一个PLinq示例,该示例抽象了从开发人员到框架的线程。
string testName = "foo";
string fullTestName;
var testIterations = 100;
Enumerable.Range(0, testIterations).AsParallel().ForAll(i=>
{
PerformanceTest(testName,i,numberOfRows);
});
void PerformanceTest(String testName, int iterationNumber, long numberOfRows)
{
// Insert a bunch of rows into DB
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.