开发者

How to write an abort-able synchronous method?

开发者 https://www.devze.com 2023-02-10 18:29 出处:网络
I need to run a list of methods synchronously, with the ability to stop the execution list. It\'s easy to stop the loop before execution using a reset event (see first line in Execute).

I need to run a list of methods synchronously, with the ability to stop the execution list. It's easy to stop the loop before execution using a reset event (see first line in Execute).

How can I wait for a response from action.Execute() and action.Execute() at the same time?

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

I think it would be easy to preform using Tasks, but unfortunately I'm using .net 3.5.


Edit: solution inspired by 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);
    }
}


That's the opposite of synchronicity.
You need to run the method on a background thread.

For example, you can call the method using Delegate.BeginInvoke, then check IAsyncResult.IsCompleted. (and make sure to call EndInvoke afterwards)


You can run Execute in another Thread, and then your while tries to Join with a timeout.

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

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

0

精彩评论

暂无评论...
验证码 换一张
取 消