【发布时间】:2013-12-25 00:52:45
【问题描述】:
我在我的应用程序中使用Task 和TaskCompletionSource 代码,用于频繁调用的场景,例如从“滚动表视图”异步下载 Internet 上的图像。这允许我编写异步/等待代码,而无需接触 UI 线程来进行下载/缓存操作。
例如:
public override Task<object> GetCachedImage (string key)
{
UIImage inMemoryImage = sdImageCache.ImageFromMemoryCache (key);
//
// Return synchronously since the image was found in the memory cache.
if (inMemoryImage != null) {
return Task.FromResult ((object)inMemoryImage);
}
TaskCompletionSource<object> tsc = new TaskCompletionSource<object> ();
//
// Query the disk cache asynchronously, invoking the result asynchronously.
sdImageCache.QueryDiskCache (key, (image, cacheType) => {
tsc.TrySetResult (image);
});
return tsc.Task;
}
GetCachedImage 被多次调用,因为一个表格视图可能有很多要下载的图像,并且用户也可以滚动表格视图。
任务本身不会花费太长时间来执行(在某些情况下结果是同步返回的),所以我希望系统创建很多线程但也可以重用它们。但是我在控制台中看到以下输出:
Thread finished: <Thread Pool> #149
线程的数量总是越来越大,我担心我的应用程序创建了太多线程,并且在长时间使用后可能会因此而卡住。 Thread finished: <Thread Pool> #149 是什么意思?是否正在创建和销毁线程?线程是否被重用?我的应用程序是否有 #149 活动线程?我可以(应该)限制最大线程数吗?
编辑
按照@usr 的建议,我再次运行我的应用程序并停止调试器以查看那里有多少线程,请参阅屏幕截图:
看起来创建了 38 个线程,但其中一些被销毁了,对吗?
这是否意味着只要应用程序正在运行,Thread finished: <Thread Pool> #... 消息将始终以更大的数字出现?为什么不重复使用线程?
【问题讨论】:
-
为什么系统还要创建线程?我没有看到任何会在您的代码中创建线程的内容。
-
我不是
ThreadPool专家,但我可以在文档中看到Task使用ThreadPool线程在后台执行工作。问题是“为什么要创建太多线程”? -
如果你使用
Task.Run()或类似的东西,当然可以。但如果您使用Task.FromResult()或TaskCompletionSource,则不会,因为这样就没有工作可做。 -
那个线程池调试输出甚至意味着什么?我不知道。这并不一定意味着有这么多线程正在运行。暂停调试器,看看有多少线程。
-
我按照@usr 的建议使用调试器输出的屏幕截图编辑了我的问题。
标签: c# mono xamarin.ios xamarin async-await