0

I've got a .Net C# application where I'm attempting to spawn multiple threads. 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.

4

4 回答 4

2

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

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);
    }
}
于 2012-11-18T19:39:46.653 回答
2

您可以使用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方法)

于 2012-11-18T18:45:27.293 回答
1

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[] 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.

于 2012-11-18T18:18:50.253 回答
-1

另一个建议是使用 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
}
于 2012-11-18T18:30:59.237 回答