如何并行运行调用一个方法

问题描述:

考虑下面的代码:如何并行运行调用一个方法

if (!string.IsNullOrEmpty(link1)) 
{ 
    string[] link1_ar = link1.Split(sep, StringSplitOptions.None); 
    string page1 = link1_ar[1]; 
    string filter1 = link1_ar[2]; 
    string code2 = link2_ar[3]; 
    MyMethod(summary, page1, filter1, code1); 
} 
if (!string.IsNullOrEmpty(link2)) 
{ 
    string[] link2_ar = link2.Split(sep, StringSplitOptions.None); 
    string page2 = link2_ar[1]; 
    string filter2 = link2_ar[2]; 
    string code2 = link2_ar[3]; 
    MyMethod(summary, page2, filter2, code2); 
} 
if (!string.IsNullOrEmpty(link3)) 
{ 
    string[] link3_ar = link3.Split(sep, StringSplitOptions.None); 
    string page3 = link3_ar[1]; 
    string filter3 = link3_ar[2]; 
    string code3 = link3_ar[3]; 
    MyMethod(summary, page3, filter3, code3); 
} 


    private void MyMethod(ref string summary, string bid_page, string bid_filter, string bid_code, string bid_silver) 
    { 
     bla bla bla 
    } 

我想在同一时间一起跑三米的MyMethod!
为了达到这个目的,我应该在这些代码中改变什么?

+1

它很大程度上取决于MyMethod中的内容,以及它是否线程安全。 –

+1

看到您已经指定这是ASP.NET,您是否打算阻止当前页面响应线程,直到完成所有三个“MyMethod”后台调用? –

+2

考虑到'summary'作为'ref'传递给每个人,很可能'MyMethod'修改'summary',所以它当前不是线程安全的。那个换成了'StringBuilder'适当线程同步,它可能会是好的,但如果多数'MyMethod'是字符串操作的工作,那么将是同步之外进行很少的工作,因此并行执行此操作的好处不大。 –

假设你的MyMethod实际上是线程安全的,然后下面应该工作使用Parallel.ForEach()方法在.NET 4.0中。我正在跟踪ConcurrentDictionary中的各个摘要,以便您可以稍后根据需要通过链接引用它们。

我还假定你改变了MyMethod()来返回摘要。

List<string> links = new List<string>() { link1, link2, link3}; 

ConcurrentDictionary<string, string> summariesByLink = new ConcurrentDictionary<string, string>(); 

Parallel.ForEach(links, link => { 

    if (!string.IsNullOrEmpty(link)) 
    { 
    string[] link_ar = link.Split(sep, StringSplitOptions.None); 
    string page = link_ar[1]; 
    string filter = link_ar[2]; 
    string code = link_ar[3]; 
    string summary = MyMethod(page, filter, code); 

    summariesByLink.Add(link, summary); 
    } 
} 
+0

感谢的人的答案,paralellism是我的最爱。我会接受你的答案。但它possbile告诉我们学习的其他方法。 – MoonLight

+0

你是什么意思的“其他方式”?@斯科特的回答显示使用任务框架,你还有什么好奇的? –

尝试将每个调用包装到一个任务中的MyMethod中,然后等待它们全部完成。

var tasks = new List<Task>(); 

if (!string.IsNullOrEmpty(link1)) 
{ 
    string[] link1_ar = link1.Split(sep, StringSplitOptions.None); 
    string page1 = link1_ar[1]; 
    string filter1 = link1_ar[2]; 
    string code2 = link2_ar[3]; 
    var link1task = Task.Run(MyMethod(summary, page1, filter1, code1)); 
    tasks.Add(link1task); 
} 
if (!string.IsNullOrEmpty(link2)) 
{ 
    string[] link2_ar = link2.Split(sep, StringSplitOptions.None); 
    string page2 = link2_ar[1]; 
    string filter2 = link2_ar[2]; 
    string code2 = link2_ar[3]; 
    var link2task = Task.Run(MyMethod(summary, page2, filter2, code2)); 
    tasks.Add(link2task); 
} 
if (!string.IsNullOrEmpty(link3)) 
{ 
    string[] link3_ar = link3.Split(sep, StringSplitOptions.None); 
    string page3 = link3_ar[1]; 
    string filter3 = link3_ar[2]; 
    string code3 = link3_ar[3]; 
    var link3task = Task.Run(MyMethod(summary, page3, filter3, code3)); 
    tasks.Add(link3task); 
} 

Task.WaitAll(tasks.ToArray());