2014-02-24 89 views
0

我有一個C# ASP.NET MVC項目。
我基本上正在運行一個模擬(有取消選項)和整理結果。
我需要使用multi-threading,因爲我可以同時運行一百萬或更多的模擬。
我的代碼是這樣的:Parallel.For循環與線程局部變量

public class MyClass 
{ 
    private ConcurrentBag<StuffResult> StuffResults { get; set; } 
    private bool CancellationRequested { get; set; } 

    public void DoAlotOfStuff(int numberOfStuffToDo) 
    { 
     var cancellationTokenSource = new CancellationTokenSource(); 
     var options = new ParallelOptions { CancellationToken = cancellationTokenSource.Token }; 

     Task.Factory.StartNew(() => 
     { 
      if (CancellationRequested) cancellationTokenSource.Cancel(); 
     }); 

     try 
     { 
      Parallel.For(0, numberOfStuffToDo, options, a => 
      { 
       options.CancellationToken.ThrowIfCancellationRequested(); 
       var class1 = new Class1(); 
       var class2 = new Class2(); 
       var class3 = new Class3(); 
       var class4 = new Class4(class1, class2, class3); 
       var result = class4.DoStuff(); 
       StuffResults.Add(result); 
      }); 
     } 
     catch (OperationCanceledException e) 
     { 
      //handle exception 
     } 
    } 
} 

問:我怎樣才能避免實例化一個新Class1Class2Class3,並Class4對象每次迭代?我讀了this msdn的文章,但我不明白。每個線程的每個對象可能有1個。

回答

0

它看起來足夠安全,我...

如果類有某種參與他們國家的話,我不知道你是否能避免初始化它們。如果沒有,你可能能夠在循環外部聲明類,或者使DoStuff方法是靜態的,所以你根本不需要實例化類。

0

我會做這樣的:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ParallelTest 
{ 
    class Program 
    { 
     static AutoResetEvent autoReset = new AutoResetEvent(false); 

     static void Main(string[] args) 
     { 
      // since this is an async method it will be run in a different thread 
      DoSomething(); 

      // wait for the async method to signal the main thread 
      autoReset.WaitOne(); 

      Console.WriteLine("done"); 

     } 

     async static void DoSomething() 
     { 
      // create some common data 
      const int count = 50000; 
      const int factor = 3; 


      // create some tasks 
      var task1 = Task.Run(() => 
      { 
       int x = 0; 
       for (int i = 0; i < count * 2; ++i) 
       { 
        x += i + factor * 3; 
        Console.WriteLine("task1: " + i + factor * 3); 
       } 
       return x; 
      }); 

      var task2 = Task.Run(() => 
      { 
       int x = 0; 
       for (int i = 0; i < count * 2; ++i) 
       { 
        x += i + factor * 4; 
        Console.WriteLine("task2: " + i + factor * 4); 
       } 
       return x; 
      }); 

      var task3 = Task.Run(() => 
      { 
       int x = 0; 
       for (int i = 0; i < count * 2; ++i) 
       { 
        x += i + factor * 5; 
        Console.WriteLine("task3: " + i + factor * 5); 
       } 
       return x; 
      }); 


      // create a resulttask which will run all the tasks in parallel 
      var resultTask = Task.WhenAll(task1, task2, task3); 

      // start the task and wait till it finishes 
      var results = await resultTask; 

      // display the results 
      for (int i = 0; i < results.Length; ++i) 
      { 
       Console.WriteLine("result" + i + ": " + results[i]); 
      } 

      // signal main thread 
      autoReset.Set(); 
     } 
    } 
}