限制并行运行方法的数量
本文关键字:方法 运行 并行 | 更新日期: 2023-09-27 18:00:58
在我的类中,我有一个下载函数。现在,为了不允许太多的并发下载,我想阻止这个功能,直到"下载点"免费为止;(
void Download(Uri uri)
{
currentDownloads++;
if (currentDownloads > MAX_DOWNLOADS)
{
//wait here
}
DoActualDownload(uri); // blocks long time
currentDownloads--;
}
在C#/.NET中有现成的编程模式吗?
edit:不幸的是,我不能使用.net4.5中的功能,只能使用.net4.0
可能是这个
var parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = 3
};
Parallel.ForEach(downloadUri, parallelOptions, (uri, state, index) =>
{
YourDownLoad(uri);
});
对于这个并发问题,您应该使用Semaphore,请参阅文档中的更多信息:https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110(.aspx
对于这种情况,我用一些方法在QueryManager
这样的自定义类中创建自己的Queue<MyQuery>
:
- 每个新查询都在
Queue<MyQuery>
查询中排队 - 在每个查询答案中的每个"入队"AND之后,我调用
checkIfQueryCouldBeSent()
checkIfQueryCouldBeSent()
方法检查您的条件:伴随查询的数量,等等。在您的情况下,如果全局计数器小于5,则接受启动新查询。然后递增计数器- 递减查询答案中的计数器
只有当所有查询都是异步的时,它才有效。您必须将回调存储在MyQuery
类中,并在查询结束时调用它。
您正在进行异步IO绑定工作,不需要使用多个线程来调用Parallel.ForEach
。
您可以简单地使用BCL中公开的自然异步API,即使用HttpClient
进行HTTP调用的API。然后,您可以使用SemaphoreSlim
和异步等待的WaitAsync
方法来限制连接:
private readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(3);
public async Task DownloadAsync(Uri uri)
{
await semaphoreSlim.WaitAsync();
try
{
string result = await DoActualDownloadAsync(uri);
}
finally
{
semaphoreSlim.Release();
}
}
您的DoActualyDownloadAsync
将使用HttpClient
来完成它的工作。大致如下:
public Task<string> DoActualDownloadAsync(Uri uri)
{
var httpClient = new HttpClient();
return httpClient.GetStringAsync(uri);
}