gpt4 book ai didi

c# - 一次设置最大运行任务时等待多个异步任务

转载 作者:太空狗 更新时间:2023-10-29 22:22:30 25 4
gpt4 key购买 nike

所以我刚开始尝试理解 async、Task、lambda 等等,但我无法让它按我想要的方式工作。使用下面的代码,我希望它锁定 btnDoWebRequest,执行未知数量的 WebRequests 作为任务,并在完成所有任务后解锁 btnDoWebRequest。但是我只想要一次最多 3 个或我设置的任何数量的任务,我部分地从 Have a set of Tasks with only X running at a time 中获得.

但是在尝试并以多种方式修改我的代码之后,它总是会立即跳回并重新启用 btnDoWebRequest。当然 VS 警告我需要等待,目前在“.ContinueWith((task)”和“await Task.WhenAll(requestInfoList.Select(async i =>”) 中的异步处,但似乎无法在何处工作或如何放置所需的等待时间。当然,由于我仍在学习,所以我很有可能在这方面做错了,整个事情需要重新设计。因此,我们将不胜感激任何帮助。

谢谢

    private SemaphoreSlim maxThread = new SemaphoreSlim(3);
private void btnDoWebRequest_Click(object sender, EventArgs e)
{
btnDoWebRequest.Enabled = false;
Task.Factory.StartNew(async () => await DoWebRequest()).Wait();
btnDoWebRequest.Enabled = true;
}

private async Task DoWebRequest()
{
List<requestInfo> requestInfoList = new List<requestInfo>();
for (int i = 0; dataRequestInfo.RowCount - 1 > i; i++)
{
requestInfoList.Add((requestInfo)dataRequestInfo.Rows[i].Tag);
}
await Task.WhenAll(requestInfoList .Select(async i =>
{
maxThread.Wait();
Task.Factory.StartNew(() =>
{
var task = Global.webRequestWork(i);
}, TaskCreationOptions.LongRunning).ContinueWith((task) => maxThread.Release());
}));
}

最佳答案

首先,不要默认使用 Task.Factory.StartNew。事实上,这应该在 async 代码中避免。如果您需要在后台线程上执行代码,请使用 Task.Run

在您的情况下,无需使用 Task.Run(或 Task.Factory.StartNew)。

从最低级别开始逐步升级。您已经有一个异步 Web 请求方法,我将其重命名为 WebRequestAsync 以遵循 Task-based Asynchronous Programming命名准则。

接下来,使用 SemaphoreSlim 上的异步 API 来限制它:

await maxThread.WaitAsync();
try
{
await Global.WebRequestWorkAsync(i);
}
finally
{
maxThread.Release();
}

对每个请求信息执行此操作(注意不需要后台线程):

private async Task DoWebRequestsAsync()
{
List<requestInfo> requestInfoList = new List<requestInfo>();
for (int i = 0; dataRequestInfo.RowCount - 1 > i; i++)
{
requestInfoList.Add((requestInfo)dataRequestInfo.Rows[i].Tag);
}
await Task.WhenAll(requestInfoList.Select(async i =>
{
await maxThread.WaitAsync();
try
{
await Global.WebRequestWorkAsync(i);
}
finally
{
maxThread.Release();
}
}));
}

最后,从您的 UI 调用它(同样,不需要后台线程):

private async void btnDoWebRequest_Click(object sender, EventArgs e)
{
btnDoWebRequest.Enabled = false;
await DoWebRequestsAsync();
btnDoWebRequest.Enabled = true;
}

总而言之,只在需要时使用Task.Run;不要使用 Task.Factory.StartNew,也不要使用 Wait(请改用 await)。我有一个 async intro在我的博客上了解更多信息。

关于c# - 一次设置最大运行任务时等待多个异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23316444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com