2012-10-06 153 views
1

我遇到的問題是一些已移植到Silverlight應用程序的asmx Web服務。問題是silverlight上的asmx服務只允許異步方法調用。大多數情況下這是可以接受的,但有一個例子我真的不想要它。如何強制異步Web服務調用充當同步?

在每個Web調用塊開始時,都會調用全局函數CheckTimeout。它所做的就是調用Web方法來查看用戶的登錄令牌是否已過期,如果有,說明用戶已超時並請重新登錄。問題是,我希望CheckTimeout在返回之前完全結束。調用方法知道你在做各種事情之前仍然登錄。

我試過在CheckTimeout中使用EventWaitHandler,該方法接收來自服務器的異步結果會發出信號,但我想這裏真的只有一個線程工作,因爲如果我這樣做,請求甚至不會發送到Web服務器那樣。關於我如何做我想要做的事情的任何想法?

private static EventWaitHandle wait_for_check_login = new AutoResetEvent(false); 

    private static bool check_timeout_result = false; 

    public static void CheckTimeout() 
    { 
     rji_ws.CheckLoginAsync(login_key); 

     wait_for_check_login.WaitOne(); 

     if (check_timeout_result) 
      { 
       check_timeout_result = false; 
       return; 
      } 
      else 
      { 
       MessageBox.Show("You've timed out after a period of inactivity. Please log in again"); 
       login_key = Guid.Empty; 
       System.Windows.Browser.HtmlPage.Document.Submit(); 
      } 


    } 

    private static void CheckTimeoutResults(object sender, RJI_WS.CheckLoginCompletedEventArgs e) 
    { 
     if (e.Error != null) 
     { 
      //MessageBox.Show("There was an error communicating with the server 
      wait_for_check_login.Set(); 
     } 
     else 
     { 
      check_timeout_result = e.Result; 
      wait_for_check_login.Set(); 


     } 
    } 

回答

1

如果調用沒有將它傳遞給服務器,問題可能是您錯過了CheckLoginAsync代碼中的某些內容(您沒有發佈它)。

在任何情況下,以這種方式編寫代碼將阻止主UI線程。您最好以下列方式安排您的代碼:

/// Usage: 
/// CheckLoginThen((bool result) => { CallWebServices(); }); 
void CheckLoginThen(Action<bool> a) 
{ 
    rji_ws.CheckLoginAsync(login_key, 
    (sender, e) => 
    { 
     if (e.Error != null) 
     { 
     MessageBox.Show("There was an error communicating with the server"); 
     } 
     else 
     { 
     var result = e.Result; 
     a(result); 
     } 
    }, 
    null); 
} 
0

把代碼放到一個單獨的方法(如果它不是在一個的話)並調用從處理程序checklogin服務完成。