我需要返回一个从异步事件处理程序中获取的String。我目前无法做到这一点,就好像我尝试在处理程序内部返回一样,它给了我一个错误,告诉我我不能返回任何对象,因为处理程序应该返回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 :(得分: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;
}
答案 1 :(得分: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;);
}
};
这只是一个例子,您必须为具体案例选择更多适当的委托签名。
答案 2 :(得分: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
关键字一起使用,从而在调用者中提供适当的异步支持和异常处理。