简体   繁体   English

在.Net / C#中,当我所有的工作线程都已完成处理时,有没有办法等待或得到通知?

[英]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. 此时,我将打印出结果摘要。

Here is what my code snippet looks like: 这是我的代码段的样子:

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.

相关问题 C#.Net等待所有线程完成并获取返回值 - C# .Net Wait for all threads to complete and get return values 如果会话在处理asp.net时回收,是否可以得到通知? - Is there a way to get notified if the session recycles WHILE processing an asp.net? C#等待所有线程在Main()中完成 - C# wait for all threads to finish in Main() 确定所有线程何时完成c# - Determining when all threads have finished c# C#.Net-如何使应用程序等待,直到在Library中创建的所有线程完成 - C# .Net - How to make application wait until all threads created in Library are finished C#Web请求-如何等待页面及其所有后续jquery / ajax调用完成并且页面已完全加载 - C# web request - how to wait until page and all of its subsequent jquery/ajax calls have completed and page has fully loaded 在所有后台线程池线程完成时得到通知 - be notified when all background threadpool threads are finished 为什么Task.WaitAll不等到我所有的任务都完成? C# - Why is Task.WaitAll not waiting until all of my Tasks have completed? C# 如何让我的方法等待所有线程完成? - How do I have my method wait for all threads to finish? c#Task.WhenAll(tasks)和SemaphoreSlim-如何知道所有任务何时完全完成 - c# Task.WhenAll(tasks) and SemaphoreSlim - how to know when all tasks have fully completed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM