0

複数のスレッドを生成しようとしている .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() の使用を検討しましたが、シナリオでの使用方法がわかりませんでした。

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

私が探しているのは、すべてのスレッドの実行が完了したときに通知されるか、すべてのスレッドが完了するのをアプリケーション内で待機するための正しいメカニズムです。

最も簡単な方法は、スレッドを追跡し (配列を使用)、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();
}

Task Parallel Library を使用することも別の方法ですが、一度に多くのスレッドを実行する必要はありません。その方がパフォーマンスが向上する可能性がありますが、特定の数のスレッドで何が起こるかを測定しようとしている場合は、それらすべてを実際に自分で開始する必要があります。

于 2012-11-18T18:18:50.253 に答える
-1

もう 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 に答える