APM异步编程模型

yangyi_2009 2015-08-20 07:14:34

class C
{
void X()
{
A a = new A();
State state = new State() { A = a };
IAsyncResult result = a.BeginAAA(AReceived, state);
}
void AReceived(IAsyncResult ar)
{
State state = (State)ar.AsyncState;
A a = state.A;
ResultA resA = a.EndAAA(ar);
B b = b.BeginBBB();
state.B = b;
IAsyncResult result = stream.BeginRead(BReceived, state);
}
void BReceived(IAsyncResult ar)
{
State state = (State)ar.AsyncState;
B b = state.B;
ResultB resB = b.EndRead(ar);

DoSomething(resB); // 最终结果
}
}


如果不用通过引发事件来返回结果的方法,
而是通过:
为类 C 实现一对 BeginCCC 和 EndCCC 方法;
或者为类 C 实现返回 Task<T> 的 CCCAsync 方法。
返回最终结果。应该如何实现?

...全文
154 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangyi_2009 2015-08-20
  • 打赏
  • 举报
回复
改用事件实现。 这样用一个Dictionary储存userState来实现并发和取消可以吗?

public class X
{

    public void XXXAsync(object userState)
    {
        lock (_syncRoot)
        {
            if (_userStates.ContainsKey(userState))
            {
                throw new ArgumentException("UserState must be unique.");
            }
            _userStates.Add(userState, false);
        }
        AAA(uri, userState);
    }

    public event XXXCompletedEventHandler XXXCompleted;


    public void XXXAsyncCancel(object userState)
    {
        lock (_syncRoot)
        {
            if (_userStates.ContainsKey(userState))
            {                    
                _userStates[userState] = true;
            }                
        }
    }

    
    private void AAA(object userState)
    {
        try
        {
            A a = new A();
            State state = new State(userState);
            state.A = a;
            if (IsCanceled(state.UserState))
            {
                RaiseXXXCompleted(null, true, state.UserState);
                return;
            }
            IAsyncResult result = a.BeginAAA(AAACallback, state);
        }
        catch (Exception ex)
        {
            RaiseXXXCompleted(ex, false, userState);
        }
    }

    private void AAACallback(IAsyncResult ar)
    {

        State state = (State)ar.AsyncState;
        try
        {
            A a = state.A;
            RA ra = (RA)a.EndAAA(ar);
            if (IsCanceled(state.UserState))
            {
                RaiseXXXCompleted(null, true, state.UserState);
                return;
            }
            state.RA = ra;
            B b = ra.GetB();
            state.B = b;                
            IAsyncResult result = b.BeginBBB(BBBCallback, state);
        }
        catch (Exception ex)
        {                
            RaiseXXXCompleted(ex, false, state.UserState);
        }
    }

    private void BBBCallback(IAsyncResult ar)
    {
        State state = (State)ar.AsyncState;
        try
        {
            B b = state.B;
            RB rb = b.EndBBB(ar);
            if (IsCanceled(state.UserState))
            {
                RaiseXXXCompleted(null, true, state.UserState);
                return;
            }                
            var result = DoSomething(rb);
            RaiseXXXCompleted(result, state.UserState);                
        }
        catch (Exception ex)
        {
            RaiseXXXCompleted(ex, false, state.UserState);
        }
    }

    private void RaiseXXXCompleted(string result, object userState)
    {
        lock (_syncRoot)
        {
            _userStates.Remove(userState);
        }
        // RaiseEvent
    }

    private void RaiseXXXCompleted(Exception error, bool cancelled, object userState)
    {
        lock (_syncRoot)
        {
            _userStates.Remove(userState);
        }
        // RaiseEvent
    }

    private bool IsCanceled(object userState)
    {
        lock (_syncRoot)
        {
            return (_userStates[userState] == false);
        }
    }

    private Dictionary<object, bool> _userStates = new Dictionary<object, bool>();

    private object _syncRoot = new object();

}
yangyi_2009 2015-08-20
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
B b = b.BeginBBB(); 这叫啥代码? 弄出繁琐累赘的 IAsyncResult 方式,还不如你在 C 类中声明一个事件更精练更方便。你所谓的“不用通过引发事件来返回结果的方法”是很不明智的。
打错了,应该是: B b = new B(); state.B = b; IAsyncResult result = b.BeginBBB(BReceived, state); A和B都不是我写的,没有源代码。 不想用事件是因为类C是设计成要支持并发的,所以才想弄成Begin(callback, state)通过传递state使每次调用和结果一一对应。
  • 打赏
  • 举报
回复
如果你想取看看,那么你看看自己的 a.BeginAAA 和 a.EndAAA 的源代码就好了。你会看到它比事件要繁琐和难读得多。可能你是因为看不懂自己的源代码,才来问的。
  • 打赏
  • 举报
回复
B b = b.BeginBBB(); 这叫啥代码? 弄出繁琐累赘的 IAsyncResult 方式,还不如你在 C 类中声明一个事件更精练更方便。你所谓的“不用通过引发事件来返回结果的方法”是很不明智的。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧