【发布时间】:2017-06-29 20:54:11
【问题描述】:
我有这个异步运行委托的代码:
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 方法。
标签: c# azure async-await file-storage