У меня есть приложение с расширением поиска.Это расширение запрашивает данные из хост-приложения.
Во время работы рабочего потока мне нужно запросить у пользователя обратную связь через модал NSAlert.Вызов основного потока и отображение модальных блоков блокирует все приложение, предотвращая тем самым расширение поиска для запроса данных.
Моя структура приложения выглядит следующим образом: 1 поток приложения 1 поток для прослушивания потока CFMessagePort 1 для запуска средства просмотра файлов 1 поток, выполняющий фоновую работу
, а также расширение выполняемого поиска в качестве клиентаприложение.
Создание рабочего потока
myWorker = new BackgroundWorker();
myWorker.WorkerSupportsCancellation = true;
myWorker.DoWork += new DoWorkEventHandler(delegate(Object o, DoWorkEventArgs args) {
// Time consuming task
// which may require user feedback
});
Внутри рабочего вызывайте событие, которое позже обрабатывается в специфической для ОС части приложения.
System.Threading.AutoResetEvent waitHandle = new System.Threading.AutoResetEvent(false);
controller.ConflictOccured ? .Invoke(this, new ConflictEventArgs {
Type = ConflictType.LocalFolderDeleted, OnResolve = (userChoice) => {
// Do something else
waitHandle.Set();
}
}
});
// Wait until conflict event has been handled
waitHandle.WaitOne();
Обработкасобытие, запускающее модальное.
private void HandleMyConflict(object sender, ConflictEventArgs eventArgs) {
// Invoking the UI thread
NSApplication.SharedApplication.BeginInvokeOnMainThread(() => {
var conflictAlert = new NSAlert() {
AlertStyle = NSAlertStyle.Warning, MessageText = "Foo", InformativeText = "Bar",
};
conflictAlert.AddButton("Foo");
conflictAlert.AddButton("Bar");
// Run the actual modal - this blocks everything
nint userResponse = conflictAlert.RunModal();
// Determine the user choice
// Resolve event by invoking callback
eventArgs.OnResolve(choice);
});
}
Я бы ожидал, что модальное устройство будет блокировать основной поток приложения с момента обработки события, но не поток наблюдателя и слушателя.Последний находится в совершенно другом ThreadPool.