执行异步方法的问题

时间:2011-09-08 17:44:01

标签: multithreading silverlight silverlight-4.0 asynchronous

我的代码存在问题

 if(Handlers.Count==0)
                {
                    GetHandlers();
                    while (_handlers.Count == 0)
                    {
                        Thread.Sleep(100);
                    }
                }
                return _showroomLogs;

此方法执行:

 private void GetHandlers()
        {
            WebSerive.GetHandlersCompleted += new EventHandler<GetHandlersCompletedEventArgs>(OnGetHandlersCompleted);
            WebSerive.GetHandlersAsync(_app.HandlerId);
        }

但是这个方法:

private void OnGetHandlersCompleted(object sender, GetHandlersCompletedEventArgs e)
        {
            WebSerive.GetHandlersCompleted -= new EventHandler<GetHandlersCompletedEventArgs>(OnGetHandlersCompleted);
            _handlers = e.Result;
        }

我属于后执行

return _showroomLogs;

如果我用While

删除这件作品

我必须做的,在

之前执行OnGetHandlersAsync
 return _showroomLogs;

1 个答案:

答案 0 :(得分:1)

您需要认识到,只要对序列引入异步操作,整个序列就会变为异步。使用像Sleep这样的阻止技术是99.99999%的错误选择。

重组为: -

  private void GetHandlers(int handlerID, Action<IList<Handler>> returnResult)
  {
        EventHandler<GetHandlersCompletedEventArgs> eh = null;
        eh = (s, args) =>
        {
             WebSerive.GetHandlersCompleted -= eh;
             returnResult(args.Result);
        };
        WebSerive.GetHandlersCompleted += eh;
        WebSerive.GetHandlersAsync(handerlID);
 }
然后你打电话给: -

 GetHandlers(_app.HandlerId, handlers =>
 {
      _handlers = handlers;
      // Do other stuff 
 });

修改

让我在概念层面概述这里的基本问题。假设我有按钮点击事件,它调用FuncAFuncA来电FuncBFuncB来电FuncC

  

点击 - &gt; FuncA - &gt; FuncB - &gt;跳到FuncC

整个序列是同步的,它可能看起来像: -

 void Button_Click(object sender, EventArgs e)
 {
     FuncA();
     //Do other stuff
 }

 void FuncA()
 {
     var result = FuncB();
     //Do stuff with result;
 }

 string FuncB()
 {
     return FuncC() + " World";
 }

 string FuncC()
 {
     return "Hello";
 }

但现在让我们将FuncC更改为异步操作的内容。它立即返回,但是它的返回值直到稍后才可用,它在完成后调用一个回调方法,它将结果作为参数。 FuncB的问题是它想要返回一个值,但是在FuncC的异步操作完成之前不能返回。我们需要以与FuncB相同的方式将FuncB转换为异步操作,而不是让FuncC阻塞线程。整个过程需要一直冒泡到事件中。它变成: -

 void Button_Click(object sender, EventArgs e)
 {
     FuncA(() =>
     {
         //Do other stuff after FuncA has completed
     });
 }

 void FuncA(Action callback)
 {
     FuncB(result =>
     {
         //Do stuff with result
         // then finally
         callback();
     });
 }

 void FuncB(Action<string> returnResult)
 {
     FuncC(result => returnResult(result + " World"));
 }

 void FuncC(Action<string> returnResult)
 {
     Dispatcher.BeginInvoke(() => returnResult("Hello"));
 }

当只涉及一个实际的异步操作时,此模式将执行。当你在同一个操作中进行一系列实际的异步调用时,事情开始变得非常时髦。为了避免过多的回调嵌套,需要一些框架帮助。我将AsyncOperationService称为{{1}},您可以阅读here