2013-07-22 51 views
2

我需要返回一個字符串,我從一個異步事件處理程序得到。我目前無法做到這一點,因爲如果我嘗試返回處理程序內部,它給了我一個錯誤,告訴我我不能返回任何對象,因爲處理程序應該返回void。返回一個字符串中的異步事件處理程序

這裏是我的代碼:

public String Login(String username, String password) 
    { 
     String returningData = ""; 
     Dictionary<string, object> parameters = new Dictionary<string, object>(); 
     parameters.Add("user", username); 
     parameters.Add("pass", password); 

     PostClient client = new PostClient(parameters); 
     client.DownloadStringCompleted += (senders, ex) => 
      { 
       if (ex.Error == null) 
       { 
        //Process the result... 
        return ex.Result; 
       } 
       else 
       { 
        return "An error occurred. The details of the error: " + ex.Error; 
       } 
      }; 
     client.DownloadStringAsync(new Uri("http://www.site.com/sample.php", UriKind.Absolute)); 
    } 

我怎樣才能正確地返回ex.Result /錯誤信息?

回答

0

簡單地觸發一個事件通知「外面的世界」有關操作完成。

對於這個定義委託:

public void delegate OnError(object sender, string message); 
public event OnError OnErrorEvent; 

... 



      client.DownloadStringCompleted += (senders, ex) => 
      { 
       if (ex.Error == null) 
       { 
        //Process the result... 
        return ex.Result; 
       } 
       else 
       { 
        if(OnErrorEvent != null) 
        OnErrorEvent(this, "An error occurred. The details of the error: " + ex.Error;); 
       } 
      }; 

這只是一個例子,你要選擇代表的更approriate簽名您的具體情況。

+0

嗯......好主意!我不知道爲什麼我以前無法想到這一點。 – kdh

+0

你需要兩個事件,一個是錯誤的情況下,一個用於成功的情況下,或有足夠的信息,通過它的參數 – Servy

1

你可以有方法返回一個Task<string>而不是字符串。該方法在被調用時不會返回正確的值,調用該方法將開始工作,並且該任務可以在將來某個時刻完成。您可以使用TaskCompletionSource來創建要返回的任務。

public Task<string> Login(String username, String password) 
{ 
    var tcs = new TaskCompletionSource<string>(); 
    Dictionary<string, object> parameters = new Dictionary<string, object>(); 
    parameters.Add("user", username); 
    parameters.Add("pass", password); 

    PostClient client = new PostClient(parameters); 
    client.DownloadStringCompleted += (senders, ex) => 
    { 
     if (ex.Error == null) 
     { 
      //Process the result... 
      tcs.TrySetResult(ex.Result); 
     } 
     else 
     { 
      string errorMessage = "An error occurred. The details of the error: " + ex.Error; 
      //todo use a more derived exception type 
      tcs.TrySetException(new Exception(errorMessage)); 
     } 
    }; 
    client.DownloadStringAsync(new Uri("http://inkyapps.mobilemp.net/scripts/PHP/socialnet/login.php", UriKind.Absolute)); 

    return tcs.Task; 
} 
+0

是否的Windows Phone 8支持的任務類來處理這兩種情況下一個事件? System.Threading.Tasks不存在...... – kdh

+0

@AndrewKim它不應該,是的,但我不是一個winphone開發人員,所以我真的不知道什麼可能是關於它的不同。 – Servy

0

我想包此成一個Task<string>,並返回:

public Task<string> LoginAsync(String username, String password) 
{ 
    var results = new TaskCompletionSource<string>(); 
    Dictionary<string, object> parameters = new Dictionary<string, object>(); 
    parameters.Add("user", username); 
    parameters.Add("pass", password); 

    PostClient client = new PostClient(parameters); 
    client.DownloadStringCompleted += (senders, ex) => 
     { 
      if (ex.Error == null) 
      { 
       results.TrySetResult(ex.Result); 
      } 
      else 
      { 
       results.TrySetException(ex.Error); // Set the exception 
      } 
     }; 
    client.DownloadStringAsync(new Uri("http://inkyapps.mobilemp.net/scripts/PHP/socialnet/login.php", UriKind.Absolute)); 

    return results.Task; 
} 

那麼這將允許您直接使用此方法與async/await關鍵字,提供適當的支持異步和異常在呼叫者處理。