异步函数中的计数器

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); 行那样将其写入控制台,不如增加一些价值。希望这对您有所帮助,或者至少能引导您走上一条新路!