I need to send information to server using WCF. I am currently using WebClient to call WCF with json data. Now, with background task, I am calling the same WCF with json, but the callback function of UploadStringAsync never gets called. I also tried HttpWebRequest, but it is not working too.
I can see in the documentation that HttpWebRequest is supporte开发者_如何学Cd in Background Tasks.
Below is the code that is handling WCF request/response:
public class Communication
{
#region Private Variables
/// <summary>
/// Callback method passed to MakeHttpPostRequest will be set to below variable.
/// This variable holds the reference to callback function and used to invoke the method passed by MakeHttpPostRequest calling method.
/// </summary>
private Action<string> action;
private Action<string, object> genericAction;
private object returnValue;
#endregion
#region Methods
/// <summary>
/// Calls WCF service using POST method.
/// </summary>
/// <param name="webserviceURL">URL of WCF service.</param>
/// <param name="json">JSON data to be posted to WCF service.</param>
/// <param name="response">Callback function that is invoked when response is received from WCF service.</param>
public void MakeHttpPostRequest(string webserviceURL, string json, Action<string> response)
{
try
{
this.action = response;
if (DeviceNetworkInformation.IsNetworkAvailable)
{
Uri uri = new Uri(webserviceURL);
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(json);
string data = Encoding.UTF8.GetString(byteArray.ToArray(), 0, (int)byteArray.Length);
WebClient webClient = new WebClient();
webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(this.WebClient_UploadStringCompleted);
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadStringAsync(uri, "POST", data);
}
else
{
if (this.action != null)
{
this.action(string.Empty);
}
}
}
catch (Exception ex)
{
if (this.action != null)
{
this.action(string.Empty);
}
new ErrorException.ErrorException().HandleError(ex, string.Empty, Global.Modules.General);
}
}
#endregion
#region Events
/// <summary>
/// Callback function that gets called when response is received from web service.
/// </summary>
/// <param name="sender">The object that raises the event.</param>
/// <param name="e">Object containing Http response details.</param>
private void WebClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
try
{
// Check whether to invoke any method
if (this.action != null)
{
// Invoke the method passed to MakeHttpPostRequest by it's calling method
this.action(e.Result);
}
else if (this.genericAction != null)
{
// Invoke the method passed to MakeHttpPostRequest by it's calling method
this.genericAction(e.Result, this.returnValue);
}
}
catch (Exception ex)
{
if (this.action != null)
{
this.action(string.Empty);
}
new ErrorException.ErrorException().HandleError(ex, string.Empty, Global.Modules.General);
}
}
#endregion
}
And using below code to send json to server:
// Send location data to server
new Common.Communication().MakeHttpPostRequest(Common.ServiceURL.TrackingTracingURL, postData, result);
Above code is working fine from application. But, does not work when called from Background Task.
There wasn't any problem with HttpWebRequest or WebClient. It was problem with calling:
NotifyComplete();
As calls on HttpWebRequest or WebClient are async, calling NotifyComplete(); was aborting execution of background task bafore response is received and was not waiting for HttpWebRequest or WebClient response.
Does anybody have workaround for this?
As Paul mentioned in his comment, it's likely that your background task is being terminated after 25 seconds of inactivity. If your task is forcefully terminated 3 (?) times it will be unscheduled until your application schedules it again (I believe they can also get perma-banned if it keeps up, but not I'm 100% sure on this).
Edit
NotifyComplete();
can occur in an asynchronous callback. Just move it to the end of your callback, after you've finished processing the response.
精彩评论