繁体   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?

我有一个.Net C#应用程序,试图在其中生成多个线程。 该应用程序用于性能测试,是一个简单的控制台应用程序。 产生线程的部分工作正常。

我正在寻找的是正确的机制,要么在所有线程完成执行时收到通知,要么在我的应用程序中等待所有线程完成。 此时,我将打印出结果摘要。

这是我的代码段的样子:

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
}

我已经看过使用RegisterWaitForSingleObject(),但无法弄清楚如何在我的方案中使用它。

您可以使用Task而不是Thread 它为您提供了比并行操作更高的抽象级别,以及一个不错的同步方法库。 例如,您可以使用以下命令等待所有任务完成。

IEnumerable<Task> BeginParallelTests(string fullTestName, int numberOfThreads)
{
    for(var index = 0; index < numberOfThreads; index++)
    {
        yield return Task.Factory.StartNew(
            () => PerformanceTest(fullTestName, index, numberOfRows));
    }
}

然后,在您的主要方法中,您可以只使用:

Task.WaitAll(BeginParallelTests(testName, numberOfThreads));

(也许您必须使用类似ToArray()来强制枚举BeginParallelTest方法)

尝试使用任务而不是线程。

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);
    }
}

我正在寻找的是正确的机制,要么在所有线程完成执行时收到通知,要么在我的应用程序中等待所有线程完成。

最简单的方法是跟踪线程(使用数组),然后依次在每个线程上调用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();
}

使用任务并行库是另一种选择,但是您一次可能没有很多线程在运行-这样可能会更好地执行,但是如果您要衡量特定数量的线程会发生什么,您可以需要真正地自己启动它们。

另一个建议是使用PLinq或新的asynch关键字提高抽象水平。

这是一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM