Мне нужно запустить список методов синхронно, с возможностью остановить список выполнения. Легко остановить цикл перед выполнением с помощью события сброса (см. Первую строку в Execute
).Как написать прерывистый синхронный метод?
Как подождать ответа от action.Execute()
и action.Execute()
в то же время?
private ManualResetEvent _abortingToken = new ManualResetEvent(false);
private List<IAction> _actions;
public void Abort()
{
_abortingToken.Set();
}
public void Execute()
{
foreach (var action in _actions)
{
if (_abortingToken.WaitOne(0))
break; // Execution aborted.
action.Execute(); // Somehow, I need to call this without blocking
while (/*Execute not finished*/)
{
if (_abortingToken.WaitOne(1))
action.Abort();
}
}
}
Я думаю, что было бы легко преформировать, используя Задачи, но, к сожалению, я использую .net 3.5.
Edit: решение вдохновлен SLaks answer:
public void Execute()
{
Action execute = null;
IAsyncResult result = null;
foreach (var action in _actions)
{
execute = new Action(scriptCommand.Execute);
if (_abortingToken.WaitOne(0))
break; // Execution aborted.
result = execute.BeginInvoke(null, null);
while (!result.IsCompleted)
{
if (_abortingToken.WaitOne(10))
{
action.Abort();
break;
}
}
execute.EndInvoke(result);
}
}
спасибо. Использование 'BeginInvoke' создает очень элегантный код без большого количества накладных расходов. Но я должен назвать «EndInvoke»? Не единственная цель «EndInvoke» - вернуть возвращаемое значение или исключения? Что делать, если мне не нужен результат (т. Е. После прерывания)? – HuBeZa
@HuBeZa: Если вы не вызываете «EndInvoke», вы будете утечка памяти. – SLaks