Я использую код Task
и TaskCompletionSource
в моем приложении в сценариях, которые часто вызывают, например, загружая изображения из Интернета асинхронно из «просмотра прокрутки». Это позволяет мне написать код async/await, не касаясь потока пользовательского интерфейса для операций загрузки/кэширования.Количество применений в приложении Monotouch
.: например
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
живых потоков? Может (должен) ограничить максимальное количество потоков?
EDIT
Как было предложено @usr я побежал мое приложение снова и остановился отладчик, чтобы посмотреть, сколько потоков были там, увидеть скриншоты:
Выглядит как Было создано 38 потоков, но некоторые из них были уничтожены, я прав? Означает ли это, что сообщение Thread finished: <Thread Pool> #...
будет отображаться с большим номером, пока приложение работает? Почему не используются нити?
Почему система даже создавала потоки? Я не вижу ничего, что могло бы создать поток в вашем коде. – svick
Я не эксперт «ThreadPool», но я вижу в документации, что 'Task' использует потоки ThreadPool для выполнения работы в фоновом режиме. Проблема заключается в том, «почему создается слишком много потоков»? –
Если вы используете 'Task.Run()' или что-то в этом роде, конечно. Но нет, если вы используете 'Task.FromResult()' или 'TaskCompletionSource', потому что тогда нет работы для выполнения. – svick