WhenAll如何处理任务



我的asp.net控制台应用程序中有以下代码,用于在20个请求的并行调用一个名为gettingCustomerInfo的方法,如下所示:

class Program
{
static SemaphoreSlim throttler = new SemaphoreSlim(initialCount: 20);
private static async Task<ScanInfo> gettingCustomerInfo(string website,
string phone, long companyId)
{
await throttler.WaitAsync();
ScanInfo si = new ScanInfo() { companyId = companyId };
try
{
//code goes here...
}
finally
{
throttler.Release();
}
}
static async Task Main(string[] args)
{
bool hasmore = true;
string offset = string.Empty;
bool first = true;
try
{
while (hasmore || first)
{
Marketing ipfd = new Marketing();
first = false;
try
{
// call the PM API to get the account id 
using (WebClient wc = new WebClient())
{
wc.Encoding = Encoding.UTF8;
string url = "https://api.hubapi.com/companies/v2/companies/" +
"paged?hapikey=******properties=website" +
"&properties=mse_scan&properties=phone" +
"&limit=" + 100 + "&offset=" + offset;
string tempurl = url.Trim();
var json = wc.DownloadString(tempurl);
ipfd = JsonConvert.DeserializeObject<Marketing>(json);
int rrr = ipfd.companies.Count();
offset = ipfd.offset;
hasmore = ipfd.hasmore;
}
}
catch (Exception e)
{
}
var tasks = ipfd.companies
.Select(c => Task.Run(() => gettingCustomerInfo
(
c.properties.website.value,
(
c.properties.phone != null &&
!String.IsNullOrEmpty(c.properties.phone.value) ?
c.properties.phone.value : null
),
c.companyId
)
));
var results = await Task.WhenAll(tasks);
}
}
}
}

现在我不知道我的代码的逻辑和流程将如何运行?现在在API调用中我得到了100个项目,然后在gettingCustomerInfo中我定义了一个SemaphoreSlim = 20。但我不确定我的代码流会如何?有人能给我建议吗?

第1版

现在我在gettingCustomerInfo方法中添加了以下内容:-

private static async Task<ScanInfo> gettingCustomerInfo(string website,string phone, long compnayId)
{

Console.WriteLine("a");
await throttler.WaitAsync();
ScanInfo si = new ScanInfo() { companyId = compnayId };

Console.WriteLine("b");

我得到了这样的模式:-

a
a
a
a
a
a
a
b
b
a
b
a
b
b
b
a
b
a
b
b
a
b
b
b
a
b
a
b
a
b
a
b
a
b

现在在api调用中我得到了100个项目,然后在gettingCustomerInfo中我定义了SemaphoreSlim=20。但我不确定我的代码流会如何?

所以companies有100个项目,这些项目每个都被Select分解成任务。

当此代码调用Task.WhenAll时,将创建所有100个任务,并调用gettingCustomerInfo100次。

await throttler.WaitAsync的前20个调用将立即完成并继续执行,运行//code goes here。当每一个完成时,它将调用Release,从而完成在await throttler.WaitAsync等待的80个调用中的一个。

最终,所有100个调用将完成运行//code goes here(一次不超过20个(,然后await Task.WhenAll完成。

最新更新