异步多线程异常处理? [英] Asynchronous Multithreading Exception Handling?

查看:203
本文介绍了异步多线程异常处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的异步编程(的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到DoS​​omeAsynchWorkDelegate,因为我们传递它作为第二个参数的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆