Reputation: 681
First post here, sorry for starting with asking questions.
In my Windows Phone 7 app I have a working livetile that is beeing triggered by a background agent. But how can I modify the code so the httpwebrequest timeouts after 10 seconds?
Thanks in advance.
protected override void OnInvoke(ScheduledTask task)
{
//TODO: Add code to perform your task in background
var request = (HttpWebRequest)WebRequest.Create(
new Uri("site.com"));
request.BeginGetResponse(r =>
{
var httpRequest = (HttpWebRequest)r.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
using (var reader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = reader.ReadToEnd();
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
string strResult = response;
/// If application uses both PeriodicTask and ResourceIntensiveTask
if (task is PeriodicTask)
{
// Execute periodic task actions here.
ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("TileID=2"));
if (TileToFind != null)
{
StandardTileData NewTileData = new StandardTileData
{
BackgroundImage = new Uri("Pin-to-start.png", UriKind.Relative),
Title = strResult,
Count = null
};
TileToFind.Update(NewTileData);
}
}
else
{
// Execute resource-intensive task actions here.
}
NotifyComplete();
}));
}
}, request);
}
Upvotes: 0
Views: 623
Reputation: 26344
But how can I modify the code so the httpwebrequest timeouts after 10 seconds?
You mean so it'll call NotifyComplete()
regardless of timeouts?-) The catch is that after 15 seconds the task terminates, and gets disabled until it's re-launched by the user (inside your app).
I would recommend using TPL for Silverlight and utilizing the ability to use Tasks for setting a Timeout.
Something like:
protected override void OnInvoke(ScheduledTask task)
{
var fetchTask = FetchData(TimeSpan.FromSeconds(10));
fetchTask.ContinueWith(x =>
{
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
string strResult = x.Result; // mind you, x.Result will be "null" when a timeout occours.
...
NotifyComplete();
}));
});
}
private Task<string> FetchData(TimeSpan timeout)
{
var tcs = new TaskCompletionSource<string>();
var request = (HttpWebRequest)WebRequest.Create(new Uri("site.com"));
Timer timer = null;
timer = new Timer(sender =>
{
tcs.TrySetResult(null);
timer.Dispose();
}, null, (int)timeout.TotalMilliseconds, Timeout.Infinite);
request.BeginGetResponse(r =>
{
var httpRequest = (HttpWebRequest)r.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
using (var reader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = reader.ReadToEnd();
tcs.TrySetResult(response);
}
});
return tcs.Task;
}
Upvotes: 2
Reputation: 913
Here is copy/paste from code that i use in one of my apps. It will abort the connection after 60 seconds.
private static void DoWebRequest(string uri)
{
string id = "my_request";
Timer t = null;
int timeout = 60; // in seconds
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Accept = "*/*";
request.AllowAutoRedirect = true;
// disable caching.
request.Headers["Cache-Control"] = "no-cache";
request.Headers["Pragma"] = "no-cache";
t = new Timer(
state =>
{
if (string.Compare(state.ToString(), id, StringComparison.InvariantCultureIgnoreCase) == 0)
{
logger.Write("Timeout reached for connection [{0}], aborting download.", id);
request.Abort();
t.Dispose();
}
},
id,
timeout * 1000,
0);
request.BeginGetResponse(
r =>
{
try
{
if (t != null)
{
t.Dispose();
}
// your code for processing the results
}
catch
{
// error handling.
}
},
request);
}
catch
{
}
}
Upvotes: 3