2

マルチスレッドプログラムですべてのスレッドがいつ終了したか知りたい

プーリングのようなものなしで

while(!allThreadFinished){
thread.sleep(100);
}

ソリューションはモニターを使用する必要がありますが、それが正しいことをどのように承認できますか。次のコードの「SomeMethod」はネットワークを使用しているため、時間がかかります。

public object SomeMethod(string input);
public object[] MultiThreadMethod(string[] inputs) {
            var result = new object[inputs.Count()];
            int i = 0;
            foreach (var item in inputs) {
                BackgroundWorker work = new BackgroundWorker();
                work.DoWork += (sender, doWorkEventArgs) => { doWorkEventArgs.Result = SomeMethod(item); };
                work.RunWorkerCompleted += (sender, runWorkerCompletedEventArgs) => { 
                    result[i] = runWorkerCompletedEventArgs.Result; 
                };
                i++;
                work.RunWorkerAsync();
            }
            /////////////////////////////////////////////////////////////
            //**wait while all thread has been completed**
            /////////////////////////////////////////////////////////////
            return result;
        }
4

4 に答える 4

3

TPL http://msdn.microsoft.com/en-us/library/dd460717.aspxを使用してみてください。

 List<Task> tasks = new List<Task>();

 Task t1 = new Task(() =>
 {
    // Do something here...

 });
 t1.Start();
 tasks.Add(t1);

 Task t2 = new Task(() =>
 {
    // Do something here...

 });
 t2.Start();
 tasks.Add(t2);

 Task.WaitAll(tasks.ToArray());
于 2012-10-04T14:32:07.513 に答える
2

TPL を使用して同じことを行うことができます。Thread.Sleep() を使用しないようにすると、はるかに明確になります。これをチェックしてください:http://msdn.microsoft.com/en-us/library/dd537610.aspx

TPL を使用した例は次のようになります (テストされていないコード):

    private ConcurrentBag<object> _results;
    public object[] MultiThreadMethod(string[] inputs)
    {
        _results = new ConcurrentBag<object>();
        var tasks = new Task[inputs.Length];
        for (int i = 0; i < inputs.Length; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => DoWork(inputs[i]));
        }

        Task.WaitAll(tasks);
        return _results.ToArray();
    }

    private void DoWork(string item)
    {
        _results.Add(SomeMethod(item));
    }

編集: ConcurrentBag なし:

public object[] MultiThreadMethod(string[] inputs)
    {
        var tasks = new Task<object>[inputs.Length];
        for (int i = 0; i < inputs.Length; i++)
        {
            tasks[i] = Task<object>.Factory.StartNew(() => DoWork(inputs[i]));
        }

        Task.WaitAll(tasks);
        return tasks.Select(task => task.Result).ToArray();
    }

    private object DoWork(string item)
    {
        return SomeMethod(item);
    }
于 2012-10-04T14:40:56.520 に答える
1

RunWorkerCompletedにイベントをフックしBackgroundWorkerます。作業が完了すると発火します。

BackgroundWorker を適切に使用する方法の完全な例は、ここにあります。

于 2012-10-04T14:31:02.883 に答える
0

http://msdn.microsoft.com/en-us/library/dd537608.aspx

// 順次バージョン

foreach (var item in sourceCollection)
    Process(item);

// 同等の並列

Parallel.ForEach(sourceCollection, item => Process(item));
于 2012-10-04T19:03:32.687 に答える