限制并行运行方法的数量

时间:2015-07-03 09:50:23

标签: c# .net .net-4.0

在我班上我有一个下载功能。现在为了不允许过多的并发下载,我想阻止这个功能,直到" download-spot"是免费的;)

void Download(Uri uri)
{
    currentDownloads++;

    if (currentDownloads > MAX_DOWNLOADS)
    {
        //wait here
    }

    DoActualDownload(uri); // blocks long time

    currentDownloads--;
}

在C#/ .NET中是否有现成的编程模式?

编辑:遗憾的是,我无法使用.net4.5中的功能,只能使用.net4.0

4 个答案:

答案 0 :(得分:3)

可能是这个

var parallelOptions = new ParallelOptions
{        
    MaxDegreeOfParallelism = 3
};

Parallel.ForEach(downloadUri, parallelOptions, (uri, state, index) =>
{
    YourDownLoad(uri);
});

答案 1 :(得分:2)

您应该使用信号量来解决此并发问题,请参阅文档中的更多内容: https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110).aspx

答案 2 :(得分:1)

对于这种情况,我在自定义类Queue<MyQuery>中创建了自己的QueryManager,并使用了一些方法:

  1. 每个新查询都在Queue<MyQuery>个查询
  2. 中排队
  3. 每次&#34;排队&#34;在每个查询答案中,我致电checkIfQueryCouldBeSent()
  4. checkIfQueryCouldBeSent()方法检查您的条件:伴随查询的数量,依此类推。在您的情况下,如果全局计数器小于5,则接受启动新查询。并且递增计数器
  5. 在查询答案中减少计数器
  6. 仅当所有查询都是异步时才有效。 您必须在MyQuery类中存储Callback,并在查询结束时调用它。

答案 3 :(得分:1)

您正在执行异步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);
}