Для того, чтобы выполнить долговременную работу (пусть это будет поиск в этом контексте), я поместил логику загрузки в задачу TPL, поэтому общий метод Search() is называемый фоновой нитью. Поиск() операция может быть достаточно длинной, поэтому мне нужно отменить ее правильно, используя CancellationToken. Но операция Search() не вернулась, пока она не закончилась, поэтому я должен сделать некоторую логику, чтобы реализовать удобную и (!) Быстро отмена.Шаблон для долговременной работы с возможностью отмены
Использование WaitHandle's я могу реализовать что-то вроде этого:
private void StartSearch() // UI thread
{
CancellationTokenSource s = new CancellationTokenSource();
Task.Factory.StartNew(() => StartSearchInternal(s.Token), s.Token)
}
private void StartSearchInternal(CancellationToken token) // Main Background Thread
{
ManualResetEvent eHandle = new ManualResetEvent(false);
Task.Factory.StartNew(() => Search(eHandle), TaskScheduler.Default);
WaitHandle.WaitAny(new [] { eHandle, token.WaitHandle });
token.ThrowIfCancellationRequested();
}
private IEnumerable<object> Search(ManualResetEvent e) // Another Background thread
{
try
{
// Real search call, i.e. to database, service, or AD, doesn't matter
return RealSearch();
}
catch {} // Here, for simplicity of question, catch and eat all exceptions
finally
{
try
{
e.Set();
}
catch {}
}
}
Это, мне кажется, что это не так элегантное решение, которое может быть сделано.
Вопрос: Есть ли какие-либо другие подходы для этой задачи?
Помогло ли это? http://stackoverflow.com/questions/13513650/how-to-set-timeout-for-a-line-of-c-sharp-code/13513854 – Carsten
@ Aschratt - Нет. Мне не нужны параметры TimeOut. Мне нужна быстрая отмена. – stukselbax
Итак, вы не можете использовать 'ThrowIfCancellationRequested' внутри' StartSearchInternal', не так ли? Если это так, отметьте [«Как отменить отмененные асинхронные операции?»] (Http://blogs.msdn.com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non -cancelable Асинхр-operations.aspx). – Noseratio