2011-09-08 222 views
1

我有個問題與該代碼問題的執行異步方法

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; 
     } 

我落入afterd執行的

return _showroomLogs; 
五言的

如果我刪除這一塊有雖然

我必須這樣做,到

return _showroomLogs; 

之前已經執行OnGetHandlersAsync?

+1

你不能。這就是異步的意思。 – SLaks

回答

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 
}); 

編輯

讓我概括在概念層面fundemental問題是在這裏。可以說我有按鈕點擊事件,其中調用​​。​​來電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變成異步操作,而不是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,你可以閱讀關於here

+0

不幸的是,我有和以前一樣的情況:/ – user278618

+0

@ user278618:是的,你必須採用我所描述的模式回到原始事件。 – AnthonyWJones

+0

謝謝安東尼:) – user278618