如何编写一个可中止的同步方法?

时间:2011-02-13 14:40:20

标签: c# multithreading .net-3.5 asynchronous

我需要同步运行一个方法列表,并能够停止执行列表。使用重置事件执行之前很容易停止循环(参见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();
        }
    }
}

我认为使用Tasks进行预处理很容易,但不幸的是我使用的是.net 3.5。


编辑解决方案受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);
    }
}

2 个答案:

答案 0 :(得分:2)

这与同步性相反 您需要在后台线程上运行该方法。

例如,您可以使用Delegate.BeginInvoke调用该方法,然后选中IAsyncResult.IsCompleted。 (并确保之后调用EndInvoke

答案 1 :(得分:0)

你可以在另一个线程中运行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