【问题标题】:Parallel ForEach loop Cancellation within event事件内的并行 ForEach 循环取消
【发布时间】:2015-09-29 22:54:03
【问题描述】:

我在 asp.net 网页上的事件中运行了一个并行的 foreach 循环。 如何使用取消令牌取消它?这可能是一个非常长的操作 - 困扰我的是 - 它似乎在操作运行时回发 - 那么如何触发另一个事件以使用取消令牌?这可能吗?

protected void btnSend_Click(object sender, EventArgs e)
{
    mailList = tbEmailTo.Text.Split(
        new string[] { "," }, 
        StringSplitOptions.RemoveEmptyEntries).ToList();
    Parallel.ForEach(emailList, email =>
    {   
        //just sending email  
    });
}

【问题讨论】:

  • 我没有看到在该代码中触发了任何事件?
  • Split 之后你真的不需要那个ToListParallel.ForEach 也可以与数组一起使用。

标签: c# asp.net


【解决方案1】:

将 Parallel.ForEach CancellationToken 传递给您,如果请求取消,请检查循环内部。如果它被请求,它将抛出异常并退出你的循环。调用

cts.Cancel();

从您的循环外部将 CancellationToken 设置为 Cancel 状态,它会在您的 Parallel.ForEach 循环内引发异常。

CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;

try
{
    Parallel.ForEach(emailList, po, (email) =>
    {
        //just sending email here

        po.CancellationToken.ThrowIfCancellationRequested();
    });
}
catch (OperationCanceledException e)
{
}
finally
{
    cts.Dispose();
}

【讨论】:

  • 这是我不明白的 - 我如何在回发期间触发事件来告诉事情取消?
  • 这不是 Windows 窗体应用程序
  • @JohnAshton,请看这篇帖子forums.asp.net/t/… 他们正在使用 ASP.NET 从 webforms 中取消长时间运行的任务
  • 这篇文章从来没有给出具体的答案——似乎没有办法做到这一点?
【解决方案2】:

它肯定不会取消并行循环的发送部分,因为该代码不知道或不了解您的取消令牌。如果您需要立即停止而不是优雅地取消,那么您应该考虑编写自己的线程,以便您可以终止整个线程。或者至少使用一个不同的库,在它自己的线程中运行你的代码,比如私有线程池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2016-12-31
    相关资源
    最近更新 更多