我有這樣的代碼異步運行的委託:異步Azure的文件存儲 - 上傳任務等待其它任務
public delegate void FileHandler(string path);
....
FileHandler fileHandler = HandleFile;
foreach (FileInfo file in files)
{
string filePath = file.FullName;
if (IO.FileAvailable(filePath))
{
fileHandler.BeginInvoke(filePath, null, null); // i call EndInvoke later
}
}
這裏是代表,剛剛上傳的東西到Azure的文件存儲:
private static void HandleFile(string path)
{
AzureStorage.Instance.UploadFile("some-key", path);
}
此外,這是上傳功能:
public async Task UploadFileAsync(string storageKey, string filePath)
{
CloudFile loc = Navigate(storageKey);
await TransferManager.UploadAsync(filePath, loc);
}
public void UploadFile(string storageKey, string filePath)
{
Task uploadTask = UploadFileAsync(storageKey, filePath);
Console.WriteLine("Will wait for " + storageKey + " path: " + filePath + " with thread: " + Thread.CurrentThread.ManagedThreadId);
uploadTask.Wait();
Console.WriteLine(">>> Done waiting for " + storageKey + " path: " + filePath);
uploadTask.Dispose();
}
這裏是我的輸出:
Will wait for /bills/test/SomePdfName_1.pdf path: C:\test\SomePdfName_1.pdf with thread: 4
Will wait for /bills/test/SomePdfName_6.pdf path: C:\test\SomePdfName_6.pdf with thread: 7
Will wait for /bills/test/SomePdfName_10.pdf path: C:\test\SomePdfName_10.pdf with thread: 5
Will wait for /bills/test/SomePdfName_5.pdf path: C:\test\SomePdfName_5.pdf with thread: 9
Will wait for /bills/test/SomePdfName_3.pdf path: C:\test\SomePdfName_3.pdf with thread: 8
Will wait for /bills/test/SomePdfName_7.pdf path: C:\test\SomePdfName_7.pdf with thread: 11
Will wait for /bills/test/SomePdfName_4.pdf path: C:\test\SomePdfName_4.pdf with thread: 10
Will wait for /bills/test/SomePdfName_2.pdf path: C:\test\SomePdfName_2.pdf with thread: 6
Will wait for /bills/test/SomePdfName_8.pdf path: C:\test\SomePdfName_8.pdf with thread: 12
Will wait for /bills/test/SomePdfName_9.pdf path: C:\test\SomePdfName_9.pdf with thread: 13
.... 10 seconds later
>>> Done waiting for /bills/test/SomePdfName_9.pdf path: C:\test\SomePdfName_9.pdf
>>> Done waiting for /bills/test/SomePdfName_10.pdf path: C:\test\SomePdfName_10.pdf
>>> Done waiting for /bills/test/SomePdfName_1.pdf path: C:\test\SomePdfName_1.pdf
>>> Done waiting for /bills/test/SomePdfName_7.pdf path: C:\test\SomePdfName_7.pdf
>>> Done waiting for /bills/test/SomePdfName_2.pdf path: C:\test\SomePdfName_2.pdf
>>> Done waiting for /bills/test/SomePdfName_5.pdf path: C:\test\SomePdfName_5.pdf
>>> Done waiting for /bills/test/SomePdfName_6.pdf path: C:\test\SomePdfName_6.pdf
>>> Done waiting for /bills/test/SomePdfName_8.pdf path: C:\test\SomePdfName_8.pdf
>>> Done waiting for /bills/test/SomePdfName_3.pdf path: C:\test\SomePdfName_3.pdf
>>> Done waiting for /bills/test/SomePdfName_4.pdf path: C:\test\SomePdfName_4.pdf
如您所見,在任何上載任務完成之前,所有10個任務必須先進入等待狀態? 我的問題爲什麼是?這與5,10,100或1000個文件相同。
在我看來,這是與線程池的大小有關。由於 BeginInvoke和await方法都將使用線程池的線程。進程的線程池的缺省大小取決於幾個因素,例如虛擬地址空間的大小。線程的數量超過當前線程池的線程。它不會立即在所有情況下創建新線程。如果有未完成的任務,它將每0.5秒創建一個線程,最大線程數最多。所以沒有足夠的線程來執行await TransferManager.UploadAsync方法。 –