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