簡體   English   中英

限制並行運行方法的數量

[英]Limit number of parallel running methods

在我班上我有一個下載功能。 現在為了不允許過多的並發下載,我想阻止這個功能,直到“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

可能是這個

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> ,其中包含一些方法:

  1. 每個新查詢都在Queue<MyQuery>查詢中Queue<MyQuery>
  2. 在每個“enqueue”AND在每個查詢答案之后,我調用checkIfQueryCouldBeSent()
  3. checkIfQueryCouldBeSent()方法檢查您的條件:伴隨查詢的數量,依此類推。 在您的情況下,如果全局計數器小於5,則接受啟動新查詢。然后遞增計數器
  4. 在查詢答案中減少計數器

它僅在所有查詢都是異步時才有效。 您必須在MyQuery類中存儲Callback,並在查詢結束時調用它。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM