I need to return a String that I get from an Async Event Handler. I can't currently do this as if I try returning inside the handler, it gives me an error telling me I can't return any objects because the handler is supposed to return void.
Here is my code:
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));
}
How can I return ex.Result/error message correctly?
You can have the method return a Task<string>
rather than a string. The method won't return a value right when it's called, calling the method will start the work and the task can be completed at some point in the future. You can use a TaskCompletionSource
to create the task to be returned.
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;
}
Simply fire an event to notify "outside world" about completion of operation.
For this define your delegate:
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;);
}
};
This is just an example, you have to choose more approriate signature of delegate for your concrete case.
I would wrap this up into a Task<string>
, and return that:
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;
}
This will then allow you to use this method with the async
/ await
keywords directly, providing proper asynchronous support and exception handling in the caller.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.