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.
精彩评论