#c# #iphone #multithreading #xamarin.ios
#c# #iPhone #многопоточность #xamarin.ios
Вопрос:
Глядя на инструмент профилировщика времени в Instruments, похоже, что я не удаляю потоки после того, как я их использовал. Список «Всех потоков» растет по мере выполнения операций, запускающих поток.
Я запускаю свой поток следующим образом («поток» является локальным для функции):
UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true;
Thread thread = new Thread(Dispatch);
thread.Start();
Функция Dispatch() является:
private void Dispatch()
{
using (NSAutoreleasePool autoreleasePool = new NSAutoreleasePool())
{
try
{
// Calls a web service.
_workDispatcher.Dispatch();
}
finally
{
// Resets network activity indicator after thread complete.
InvokeOnMainThread(() => { UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false; });
}
}
}
_workerDispatcher.Отправка выполняет вызов веб-службы.
Что еще я должен сделать, чтобы уничтожить поток по завершении?
Приложение выходит из строя через длительный период времени — и мы предполагаем, что это могут быть потоки, — поскольку оно регулярно запускает их для выполнения коротких операций. Я читал, что мониторинг использования памяти в MonoTouch является сложной задачей из-за сборки мусора — или я бы посмотрел, используется ли также память (например, оставшимися потоками).
Я использую MonoTouch 3.2.5 и iOS 4.3.1 (и инструменты в Xcode 4). Приложение должно работать на iOS 3.x, поэтому я не могу использовать Grand Central Dispatch.
Ответ №1:
Вы уверены, что это ваши потоки? Гораздо более вероятно, что MonoTouch сохраняет некоторые потоки threadpool для будущих асинхронных операций (например, при вызове вашего веб-сервиса).
Комментарии:
1. Нет, я не уверен, что это мои потоки, я полагаю. Но их число растет каждый раз, когда я выполняю операцию, которая запускает поток. Я просмотрел его на 100 (после чего я прекратил запись). Инструменты говорят, что они запущены. Есть ли простой способ провести различие между потоками MT и app в инструментах?
2. Если у вас есть тестовый файл, который может показывать 100 запущенных потоков, когда они должны были завершиться, пожалуйста, отправьте сообщение об ошибке по адресу monotouch.net/Support и прикрепите тестовый набор
3. Я отправил тестовое приложение в службу поддержки novell.
4. Я отправил это по электронной почте monotouch@novell.com .
Ответ №2:
MonoTouch использует два вида потоков: те, которые вы запускаете вручную с помощью Thread .Запуск и те, которые создаются по требованию в ответ на вызовы асинхронных методов (внутренне многие синхронные операции являются просто оболочками вокруг асинхронных) или создаются при использовании ThreadPool.QueueUserWorkItem или при использовании планировщика задач Parallel Framework по умолчанию.
Возможно, вы видите потоки ThreadPool, которые автоматически настраиваются на N для каждого процессора (я не помню фактическое количество, но вы можете узнать через свойство в ThreadPool).
Когда вы работаете на устройстве, у вас одно ядро, поэтому количество потоков ограничено N. Когда вы работаете на iPad 2, количество потоков ограничено 2 * N, когда вы работаете на модном iMac с 8 ядрами, это число равно 8 * N. Это просто способ Mono настроить себя на большее количество процессоров.
Комментарии:
1. Я профилирую его на 3GS, так что 1 ядро. Я попытался вызвать ThreadPool. Установил maxThreads(2, 2) в моем тестовом приложении — но, похоже, это ничего не изменило. Значение по умолчанию равно 40/20.
Ответ №3:
Похоже, это была проблема со сборкой мусора. Если я отправлю вызов GC.Collect() после завершения потока количество потоков, похоже, не продолжает расти.