我有MainProcess.cs和ChildProcess.cs。Mainprocess用于收集所有所需的信息,并将所有数据提交给并行foreach循环。子进程将调用分离API。
MainProcess.cs
//MainProcess.cs
string resourceId = GenerateUID();
Parallel.ForEach(Accounts, parallelOptions, async (account) =>
{
await childProcess.ProcessMethod(resourceId, account);
});ChildProcess.cs
//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的代码。
添加实例变量
CancellationTokenSource tokenSource = new CancellationTokenSource();然后改变
var result = await client.PostAsJsonAsync($"{baseUrl}api/services/app/Process/Run", Req, tokenSource.Token);我知道,它应该使用下面的代码进行取消处理。
tokenSource.Cancel();但问题是如何从不同的函数中取消特定资源的进程?(取消特定资源‘s的进程,因为可以并发调用ProcessMethod。如果它是处理第二资源的过程,它不应该影响第二个过程。第一批resourceId必须关闭/取消)
有专家能帮我吗?
发布于 2020-11-23 15:04:05
上面提到的
代码和过程是100%正确工作的。
真的不是。async不能与Parallel一起使用。应该使用异步并发(每个线程不带线程的多个操作),而不是并行(多个线程):
//MainProcess.cs
string resourceId = GenerateUID();
var tasks = Accounts.Select(account => childProcess.ProcessMethod(resourceId, account)).ToList();
await Task.WhenAll(tasks);,但问题是如何从不同的函数中取消特定资源的进程?(取消特定资源‘s的进程,因为可以并发调用ProcessMethod。如果它是处理第二资源的过程,它不应该影响第二个过程。第一批resourceId必须关闭/取消)
你不需要在这方面做任何特殊的逻辑。您可以对所有这些操作使用相同的取消令牌,因为每个操作完成后都会忽略取消请求。
您需要添加的唯一代码是忽略任何取消异常。
就像这样:
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)
{
}
}https://stackoverflow.com/questions/64970165
复制相似问题