Как написать прерывистый синхронный метод? - PullRequest
3 голосов
/ 13 февраля 2011

Мне нужно запустить список методов синхронно, с возможностью остановки списка выполнения. Остановить цикл перед выполнением легко, используя событие сброса (см. Первую строку в 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.


Редактировать: решение, вдохновленное SLaks ответ :

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);
    }
}

Ответы [ 2 ]

2 голосов
/ 13 февраля 2011

Это противоположность синхронности.
Вам нужно запустить метод в фоновом потоке.

Например, вы можете вызвать метод с помощью Delegate.BeginInvoke, затем проверить IAsyncResult.IsCompleted. (и обязательно позвоните EndInvoke потом)

0 голосов
/ 13 февраля 2011

Вы можете запустить Execute в другом потоке, и тогда ваш while пытается присоединиться с таймаутом.

public void Execute()
{
    foreach (var action in _actions)
    {
        if (_abortingToken.WaitOne(0))
            break; // Execution aborted.

        var workThread = new Thread(action.Execute); 
        workThread.Start();

        while (!workThread.Join(100)) /Milliseconds, there is also a timespan overload
        {
            if (_abortingToken.WaitOne(1))
                action.Abort();
        }
    }
}

См. http://msdn.microsoft.com/en-us/library/system.threading.thread_methods.aspx.

...