【问题标题】:How Parallel Run Of Calling A Method如何并行运行调用方法
【发布时间】:2012-12-11 23:24:03
【问题描述】:

给定以下代码:

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!
为了达到这个目的,我应该在这些代码中进行哪些更改?

【问题讨论】:

  • 这在很大程度上取决于 MyMethod 内部的内容,以及它是否是线程安全的。
  • 既然您已经指定这是 ASP.NET,您是否打算阻塞当前页面响应线程,直到所有三个 MyMethod 后台调用完成?
  • 考虑到summary 作为ref 传递给他们每个人,很可能MyMethod 修改了summary,所以它目前不是线程安全的。将其切换到具有适当线程同步的StringBuilder,它可能没问题,但如果MyMethod 中的大部分工作是字符串操作,那么在同步之外完成的工作将非常少,因此并行执行此操作几乎没有什么好处。
  • 鉴于您迄今为止发布的信息,没有任何令人信服的理由相信将这段代码设为多线程会带来任何速度提升。
  • 如果您的 .NET 代码比 PHP 中的等效代码慢,那么我怀疑您在这里做错了。

标签: c# asp.net .net-4.0 methods parallels


【解决方案1】:

假设您的 MyMethod 实际上是线程安全的,那么以下内容应该使用 .Net 4.0 中的 Parallel.ForEach() 方法工作。我正在跟踪 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);
  }
}

【讨论】:

  • 谢谢你的回答,并行是我的最爱。我会接受你的回答。但是否有可能向我们展示其他学习方式。
  • “其他方式”是什么意思? @Scott 的回答显示使用任务框架。你还有什么好奇的?
【解决方案2】:

尝试将对 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());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2013-08-12
    • 2016-03-22
    • 2019-01-17
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    相关资源
    最近更新 更多