Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 执行异步方法存在问题_Multithreading_Silverlight_Silverlight 4.0_Asynchronous - Fatal编程技术网

Multithreading 执行异步方法存在问题

Multithreading 执行异步方法存在问题,multithreading,silverlight,silverlight-4.0,asynchronous,Multithreading,Silverlight,Silverlight 4.0,Asynchronous,我对这个代码有问题 if(Handlers.Count==0) { GetHandlers(); while (_handlers.Count == 0) { Thread.Sleep(100); } }

我对这个代码有问题

 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);
        }
当然,如果我把这件东西拿走

我必须做的是,以前执行过ONGETHADLERSASSYNC

 return _showroomLogs;

您需要认识到,一旦向序列引入异步操作,整个序列就会变为异步。使用诸如
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);
 }
编辑

让我从概念层面概述一下这里的基本问题是什么。假设我有一个按钮点击事件,它调用
FuncA
FuncA
调用
FuncB
FuncB
调用
FuncC

单击->FuncA->FuncB->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
阻塞线程,我们需要以与
FuncC
相同的方式将
FuncB
转换为异步操作。整个过程需要一路冒泡到活动。它变成:-

 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"));
 }
void按钮\u单击(对象发送方,事件参数e)
{
FuncA(()=>
{
//在FuncA完成后做其他事情
});
}
void FuncA(操作回调)
{
FuncB(结果=>
{
//用结果做事
//最后
回调();
});
}
无效函数B(操作返回结果)
{
FuncC(result=>returnResult(result+“World”);
}
无效函数(操作返回结果)
{
Dispatcher.BeginInvoke(()=>returnResult(“Hello”);
}

当只涉及一个实际的异步操作时,就可以使用此模式。当您在同一个操作中进行一系列实际的异步调用时,事情开始变得非常棘手。为了避免过度的回调嵌套,需要一点框架帮助。我把我的称为
AsyncOperationService
,你可以读到它。

你需要认识到,一旦你把一个异步操作引入一个序列,整个序列就变成了异步的。使用诸如
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);
 }
编辑

让我从概念层面概述一下这里的基本问题是什么。假设我有一个按钮点击事件,它调用
FuncA
FuncA
调用
FuncB
FuncB
调用
FuncC

单击->FuncA->FuncB->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
阻塞线程,我们需要以与
FuncC
相同的方式将
FuncB
转换为异步操作。整个过程需要一路冒泡到活动。它变成:-

 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"));
 }
void按钮\u单击(对象发送方,事件参数e)
{
FuncA(()=>
{
//在FuncA完成后做其他事情
});
}
void FuncA(操作回调)
{
FuncB(结果=>
{
//用结果做事
//最后
回调();
});
}
无效函数B(操作返回结果)
{
FuncC(result=>returnResult(result+“World”);
}
无效函数(操作返回结果)
{
Dispatcher.BeginInvoke(()=>returnResult(“Hello”);
}

当只涉及一个实际的异步操作时,就可以使用此模式。当您在同一个操作中进行一系列实际的异步调用时,事情开始变得非常棘手。为了避免过度的回调嵌套,需要一点框架帮助。我把我的称为
AsyncOperationService
,你可以阅读它。

你不能。异步就是这个意思,你不能。这就是async的意思。不幸的是,我的情况和以前一样:/@user278618:是的,你会的,你必须按照我概述的模式回到原始事件。不幸的是,我的情况和以前一样:/@user278618:是的,你会的,您必须按照我所概述的模式返回到原始事件。