异步多线程异常处理? [英] Asynchronous Multithreading Exception Handling?
问题描述
我想在我的异步编程(的BeginInvoke / EndInvoke会)异常处理方法,其中如果线程(的BeginInvoke)中的任何一个失败,那么我希望所有其他 - 异步处理线程停止工作。请提出一些解决方案?下面我附上我的样本code也:
公开名单< ThreadResultDto> SendMailAsynch(列表< ThreadRequestDto> requestDto)
{
清单< ThreadResultDto> resultDto =新的List< ThreadResultDto>();
清单<&的IAsyncResult GT; asyncResults =新的List<&的IAsyncResult GT;(); 的foreach(在requestDto ThreadRequestDto T)
{
//创建一个代表。
DoSomeAsynchWorkDelegate德尔=新DoSomeAsynchWorkDelegate(DoSomeAsynchWork);
//启动异步调用
IAsyncResult的一个= del.BeginInvoke(T,空,德尔);
// IAsyncResult的一个= del.BeginInvoke(T,NULL,NULL);
asyncResults.Add(一);
} 的foreach(在asyncResults IAsyncResult的AR)
{
//等待每一个来完成,然后调用EndInvoke,传递的IAsyncResult。
//我们投ar.AsyncState到DoSomeAsynchWorkDelegate,因为我们传递它作为第二个参数的BeginInvoke。
ar.AsyncWaitHandle.WaitOne(); // IAsyncResult的的AsyncState属性用于获取用于调用该方法的委托
DoSomeAsynchWorkDelegate德尔=(DoSomeAsynchWorkDelegate)ar.AsyncState; //调用EndInvoke来获取结果。结果添加到项目的列表。
resultDto.Add(del.EndInvoke(AR));
} 返回resultDto;
}
最好的办法可能是使用共享的 ManualResetEvent的
例如:
MyClass类
{
私人的ManualResetEvent workFailedEvent =新的ManualResetEvent(假); 公开名单< ThreadResultDto> SendMailAsynch(列表< ThreadRequestDto> requestDto)
{
workFailedEvent.Reset(); // ---你的code的写在您的文章,其余---
} 私人无效DoAsyncWorkFirst()
{
尝试
{
的for(int i = 0; I< 10000;我++)
{
如果(workFailedEvent.WaitOne(0,真))
{
打破;
} // - 在这里做一些工作---
}
}
赶上(MyException)
{
workFailedEvent.Set();
}
} 私人无效DoAsyncWorkSecond()
{
尝试
{
对于(INT J = 0; J< 20000; J ++)
{
如果(workFailedEvent.WaitOne(0,真))
{
打破;
}
// ---在这里做一些不同的工作---
}
}
赶上(MyOtherException)
{
workFailedEvent.Set();
}
}
}
这里的有趣的部分是调用的 WaitOne的(0,TRUE)。如果您使用的0超时那么线程不会阻止。由于在 ManualResetEvent的由操作系统同步,这种特殊的方法调用,检查是否有信号,而不必担心竞争条件或实现自己的锁定的便捷方式。
I want to have an exception handling approach in my Asynchronous programming (beginInvoke/endInvoke) wherein if any one of the thread(beginInvoke) fails, then I want all other asynchrounous processing thread to stop working. Please suggest some solution?, below I am attaching my sample code also:
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;
}
The best way is probably to use a shared ManualResetEvent.
For example:
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();
}
}
}
The interesting part here is the call to WaitOne(0, true). If you use a timeout of 0 then the thread will not block. Since the ManualResetEvent is synchronized by the OS, this particular method call is a convenient way to check for a signal without having to worry about race conditions or implement your own locking.
这篇关于异步多线程异常处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!