2013-07-22 25 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关键字,提供适当的支持异步和异常在呼叫者处理。