【发布时间】:2019-02-10 16:04:26
【问题描述】:
假设我有一个添加帐户的网络服务。我应该使用此服务来添加帐户列表:
"40701", "40702", "40703", "40704", "40705"
出于测试目的,我尝试模拟此服务的不稳定工作,特别是在第一次尝试添加前三个帐户时,其他两个帐户进入第二轮的情况。第二次尝试只添加“40704”账号,“40705”账号进入第三轮,第三次添加。
public class AddingAccounts
{
int triesCount = 0;
// decision table to add accounts
readonly int[][] dt =
{
new int[] { 1, 2, 3 },
new int[] { 4 },
new int[] { 5 }
};
List<int> result = new List<int>();
public async Task<List<string>> GetAccountsAsync()
{
await Task.Delay(1500);
return new List<string> { "40701", "40702", "40703", "40704", "40705" };
}
public async Task<int> AddAccount(string account)
{
try
{
await Task.Delay(1000);
// define accounts at the current attempt
var accountsToAdd = dt[triesCount].Select(x => $"4070{x}");
if (accountsToAdd.Contains(account))
{
// simulate successful operation, return id account
return new Random().Next(100);
}
else
{
throw new InvalidOperationException($"Account {account} was not added");
}
}
catch (Exception ex)
{
ex.Data["account"] = account;
throw;
}
}
public async Task<List<int>> AddAccountsAsync(List<string> accounts)
{
var tasks = accounts.Select(ac => AddAccount(ac));
Task<int[]> allTasks = Task.WhenAll(tasks);
try
{
var res = await allTasks;
result.AddRange(res);
}
catch
{
// how can I add returned values of successfully completed tasks to result variable here ?
// I tried to use tasks variable as John advised
foreach (var t in tasks)
{
// but most tasks have WaitingForActivation status and Result of 0
if (t.Status == TaskStatus.RanToCompletion)
{
result.Add(t.Result);
}
}
List<string> failedToAddAccounts = new List<string>();
AggregateException ae = allTasks.Exception;
foreach(var ex in ae.Flatten().InnerExceptions)
{
if (ex.Data["account"] is string failedAccount)
{
failedToAddAccounts.Add(failedAccount);
}
}
triesCount++;
return await AddAccountsAsync(failedToAddAccounts);
}
return result;
}
}
我想获取所有五个帐户的 ID。
如何获得try/catch块中成功完成任务的结果?我的意思是在第一轮等待allTasks,allTasks 的状态为Faulted,我无法获得第一个添加帐户的返回值。
【问题讨论】:
-
您已经在
tasks中拥有原始任务。到allTasks完成时,所有这些都将完成(无论是否成功),所以使用这些任务。 -
你为什么有
new Random().Next(100)?你知道这很可能会导致重复的数字不是随机的吗?new Random()应始终为每个线程创建一次以避免此错误。 -
通过这行代码,我只返回了一些 id。正如我所说,我模拟了添加帐户并返回其 ID 的 Web 服务方法。所以,实际上,它们是否独特并不重要。无论如何,谢谢你的评论,我不知道。
标签: c# async-await task task-parallel-library