异步函数中的计数器
Counter inside asynchronous functions
我正在尝试实现多重下载功能,它会同时触发和下载 10 个文件。
我也实现了 IProgress 接口,让我知道它的进度。
我现在需要的是在每个文件中有一个简单的计数器,上面写着:这是下载#1,这是下载#2,等等。
我不能做一个普通的计数器,因为它们可能同时 运行 并更新我之前的计数器 using/storing 值,导致我的值错误或相同他们中的许多人的价值。
我已经研究了 Interlocked class,但我只是找不到合适的实现,它会为触发的每个异步动态函数存储一个特定的数字。
我正在使用数字将进度存储在数组中,所以我会这样调用:
IProgress<double> progressHandler = new Progress<double>(p => HandleUnitProgressBar(p, downloadIndex));
并让处理程序将进度存储在数组的指定单元格中。
谁能指出我正确的方向?
编辑 #1:添加我正在尝试使用的代码:
for (int i = 0; i < _downloadList.Count; i++)
{
var url = _downloadList.ToArray()[i];
Task.Factory.StartNew
(
async () =>
{
try
{
MegaApiClient client = new MegaApiClient();
//client.LoginAnonymous();
downloadIndex = i;
IProgress<double> progressHandler = new Progress<double>(p => HandleUnitProgressBar(p, downloadIndex));
await client.DownloadFileAsync(fileLink, url.Value, progressHandler);
}
catch (Exception e)
{
//will add later
}
}
, CancellationToken.None
, TaskCreationOptions.None
, TaskScheduler.Current
);
}
此代码的问题在于,当它到达 downloadIndex = i 时,i 已经是 4(对于 4 个同时下载),而我想向所有处理程序发送 0、1、2、3 而不是 4。
我不知道我是否完全理解你的问题,但我会试一试。如果我理解正确,您是要求将一个整数分配给请求以进行跟踪,对吗?我之前做过一些压力测试,并以 100 波为单位发送请求。代码看起来有点像这样:
static void Main(string[] args)
{
var app = new Program();
var i = 0;
var j = 0;
var tasks = new List<Task>();
while (j < 1000)
{
tasks.Add(app.CreateOpp(j));
Console.WriteLine(i);
if (i == 100)
{
var done = Task.WhenAll(tasks);
done.Wait();
i = 0;
tasks = new List<Task>();
}
i++;
j++;
}
}
private async Task CreateOpp(int i)
{
var client = new RestClient("https...");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer Token");
request.AddHeader("Content-Type", "application/json");
var response = await client.ExecuteTaskAsync(request);
Console.WriteLine(i + " Status: " + response.StatusCode);
Console.WriteLine();
}
每个任务完成后,与其像我在 "Console.WriteLine(i + " Status: " + response.StatusCode); 行那样将其写入控制台,不如增加一些价值。希望这对您有所帮助,或者至少能引导您走上一条新路!
我正在尝试实现多重下载功能,它会同时触发和下载 10 个文件。
我也实现了 IProgress 接口,让我知道它的进度。
我现在需要的是在每个文件中有一个简单的计数器,上面写着:这是下载#1,这是下载#2,等等。
我不能做一个普通的计数器,因为它们可能同时 运行 并更新我之前的计数器 using/storing 值,导致我的值错误或相同他们中的许多人的价值。
我已经研究了 Interlocked class,但我只是找不到合适的实现,它会为触发的每个异步动态函数存储一个特定的数字。
我正在使用数字将进度存储在数组中,所以我会这样调用:
IProgress<double> progressHandler = new Progress<double>(p => HandleUnitProgressBar(p, downloadIndex));
并让处理程序将进度存储在数组的指定单元格中。
谁能指出我正确的方向?
编辑 #1:添加我正在尝试使用的代码:
for (int i = 0; i < _downloadList.Count; i++)
{
var url = _downloadList.ToArray()[i];
Task.Factory.StartNew
(
async () =>
{
try
{
MegaApiClient client = new MegaApiClient();
//client.LoginAnonymous();
downloadIndex = i;
IProgress<double> progressHandler = new Progress<double>(p => HandleUnitProgressBar(p, downloadIndex));
await client.DownloadFileAsync(fileLink, url.Value, progressHandler);
}
catch (Exception e)
{
//will add later
}
}
, CancellationToken.None
, TaskCreationOptions.None
, TaskScheduler.Current
);
}
此代码的问题在于,当它到达 downloadIndex = i 时,i 已经是 4(对于 4 个同时下载),而我想向所有处理程序发送 0、1、2、3 而不是 4。
我不知道我是否完全理解你的问题,但我会试一试。如果我理解正确,您是要求将一个整数分配给请求以进行跟踪,对吗?我之前做过一些压力测试,并以 100 波为单位发送请求。代码看起来有点像这样:
static void Main(string[] args)
{
var app = new Program();
var i = 0;
var j = 0;
var tasks = new List<Task>();
while (j < 1000)
{
tasks.Add(app.CreateOpp(j));
Console.WriteLine(i);
if (i == 100)
{
var done = Task.WhenAll(tasks);
done.Wait();
i = 0;
tasks = new List<Task>();
}
i++;
j++;
}
}
private async Task CreateOpp(int i)
{
var client = new RestClient("https...");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer Token");
request.AddHeader("Content-Type", "application/json");
var response = await client.ExecuteTaskAsync(request);
Console.WriteLine(i + " Status: " + response.StatusCode);
Console.WriteLine();
}
每个任务完成后,与其像我在 "Console.WriteLine(i + " Status: " + response.StatusCode); 行那样将其写入控制台,不如增加一些价值。希望这对您有所帮助,或者至少能引导您走上一条新路!