我希望在我的异步编程(beginInvoke/endInvoke)中有一个异常处理方法,其中如果任何一个线程(beginInvoke)失败,那么我希望所有其他异步处理线程停止工作.请建议一些解决方案?,下面我也附上我的示例代码:
public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto> requestDto)
{
List<ThreadResultDto> resultDto = new List<ThreadResultDto>();
List<IAsyncResult> asyncResults = new List<IAsyncResult>();
foreach (ThreadRequestDto t in requestDto)
{
//Create a delegate.
DoSomeAsynchWorkDelegate del = new DoSomeAsynchWorkDelegate(DoSomeAsynchWork);
// Initiate the asynchronous call
IAsyncResult a = del.BeginInvoke(t,null, del);
//IAsyncResult a = del.BeginInvoke(t, null,null);
asyncResults.Add(a);
}
foreach (IAsyncResult ar in asyncResults)
{
// wait for each one to complete, then call EndInvoke, passing in the IAsyncResult.
// We cast ar.AsyncState to a DoSomeAsynchWorkDelegate, as we passed it in as the second parameter to BeginInvoke.
ar.AsyncWaitHandle.WaitOne();
//AsyncState property of IAsyncResult is used to get the delegate that was used to call that method
DoSomeAsynchWorkDelegate del = (DoSomeAsynchWorkDelegate)ar.AsyncState;
// Call EndInvoke to get the result. Add the result to the list of items.
resultDto.Add(del.EndInvoke(ar));
}
return resultDto;
}
Run Code Online (Sandbox Code Playgroud)
最好的方法可能是使用共享的ManualResetEvent。
例如:
class MyClass
{
private ManualResetEvent workFailedEvent = new ManualResetEvent(false);
public List<ThreadResultDto> SendMailAsynch(List<ThreadRequestDto> requestDto)
{
workFailedEvent.Reset();
// --- The rest of your code as written in your post ---
}
private void DoAsyncWorkFirst()
{
try
{
for (int i = 0; i < 10000; i++)
{
if (workFailedEvent.WaitOne(0, true))
{
break;
}
// -- Do some work here ---
}
}
catch (MyException)
{
workFailedEvent.Set();
}
}
private void DoAsyncWorkSecond()
{
try
{
for (int j = 0; j < 20000; j++)
{
if (workFailedEvent.WaitOne(0, true))
{
break;
}
// --- Do some different work here ---
}
}
catch (MyOtherException)
{
workFailedEvent.Set();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里有趣的部分是对WaitOne(0, true)的调用。如果使用 0 超时,则线程不会阻塞。由于ManualResetEvent是由操作系统同步的,因此这个特定的方法调用是检查信号的便捷方法,而无需担心竞争条件或实现您自己的锁定。