首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >取消并行处理

取消并行处理
EN

Stack Overflow用户
提问于 2020-11-23 14:14:49
回答 1查看 82关注 0票数 0

我有MainProcess.cs和ChildProcess.cs。Mainprocess用于收集所有所需的信息,并将所有数据提交给并行foreach循环。子进程将调用分离API。

MainProcess.cs

代码语言:javascript
复制
//MainProcess.cs

string resourceId = GenerateUID();
Parallel.ForEach(Accounts, parallelOptions, async (account) =>
{                
    await childProcess.ProcessMethod(resourceId, account);

});

ChildProcess.cs

代码语言:javascript
复制
//ChildProcess.cs

public async Task ProcessMethod(string resourceId, string account){

    var Req = {}; //Required info set in here.

    using (HttpClient client = new HttpClient())
    {

        var result = await client.PostAsJsonAsync($"{baseUrl}api/services/app/Process/Run", Req);
        if (result.IsSuccessStatusCode)
        {
            //Save returned data to DB against the resourceId. (Figure 1)
        }
    }
}

数据保存如下所示的表。

图1

有MainProcess类,它有一个并行运行任务的方法。有一个ChildProcess类,它有"ProcessMethod“。在"ProcessMethod“内部,我调用单独的API来做一些工作。上面提到的代码和程序是100%正确工作。

但我的问题是,在某种程度上我需要取消处理。让我们使用下面的“图2”使这更容易理解。

图2

根据上面的数字,整个过程将在10秒内完成。在第四秒,我需要取消处理。(呼叫1和呼叫5已经返回响应)呼叫2,呼叫3,呼叫4被发送请求,但仍然没有收到响应。

我需要做的是,在给定的时间取消所有的进程。简单地说,我在浏览器中输入了一个Url,然后点击enter。在出现网页之前,我关闭浏览器。所以我不在乎你的反应。

我试着用取消令牌来做这件事。但我坚持的地方是,我不能取消对特定resourceId的api调用。

然后我修改了ChildProcess.cs的代码。

添加实例变量

代码语言:javascript
复制
CancellationTokenSource tokenSource = new CancellationTokenSource();

然后改变

代码语言:javascript
复制
var result = await client.PostAsJsonAsync($"{baseUrl}api/services/app/Process/Run", Req, tokenSource.Token);

我知道,它应该使用下面的代码进行取消处理。

代码语言:javascript
复制
tokenSource.Cancel();

但问题是如何从不同的函数中取消特定资源的进程?(取消特定资源‘s的进程,因为可以并发调用ProcessMethod。如果它是处理第二资源的过程,它不应该影响第二个过程。第一批resourceId必须关闭/取消)

有专家能帮我吗?

EN

回答 1

Stack Overflow用户

发布于 2020-11-23 15:04:05

上面提到的

代码和过程是100%正确工作的。

真的不是。async不能与Parallel一起使用。应该使用异步并发(每个线程不带线程的多个操作),而不是并行(多个线程):

代码语言:javascript
复制
//MainProcess.cs
string resourceId = GenerateUID();
var tasks = Accounts.Select(account => childProcess.ProcessMethod(resourceId, account)).ToList();
await Task.WhenAll(tasks);

,但问题是如何从不同的函数中取消特定资源的进程?(取消特定资源‘s的进程,因为可以并发调用ProcessMethod。如果它是处理第二资源的过程,它不应该影响第二个过程。第一批resourceId必须关闭/取消)

你不需要在这方面做任何特殊的逻辑。您可以对所有这些操作使用相同的取消令牌,因为每个操作完成后都会忽略取消请求。

您需要添加的唯一代码是忽略任何取消异常。

就像这样:

代码语言:javascript
复制
public async Task ProcessMethod(string resourceId, string account)
{
  try
  {
    var Req = {}; //Required info set in here.
    using (HttpClient client = new HttpClient())
    {
      var result = await client.PostAsJsonAsync($"{baseUrl}api/services/app/Process/Run", Req, tokenSource.Token);
      if (result.IsSuccessStatusCode)
      {
        //Save returned data to DB against the resourceId. (Figure 1)
      }
    }
  }
  catch (OperationCanceledException)
  {
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64970165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档