I'm working on Windows Phone 7.1 app and want for several lines of code run for 10 seconds, if succeeds in 10 seconds, continue, if no success, stop the code and display message.
The thing is, my code is not a loop - phone tries to fetch data from a server (if internet connection is slow, might take too long).
if (DeviceNetworkInformation.IsNetworkAvailable)
{
// start timer here for 10s
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += loginHandler;
webClient.DownloadStringAsync(new Uri(string.Format(url + "?loginas=" + login + "&pass=" + pwd)));
// if 10s passed, stop code above and display MessageBox
}
You can use something like the following:
HttpClient client = new HttpClient();
var cts = new CancellationTokenSource();
cts.CancelAfter(10000);
try
{
var response = await client.GetAsync(new Uri(string.Format(url +
"?loginas=" + login + "&pass=" + pwd)), cts.Token);
var result = await response.Content.ReadAsStringAsync();
// work with result
}
catch(TaskCanceledException)
{
// error/timeout handling
}
You need the follwoing NuGet packages:
HttpClient
async/await
Make that piece of code a method, make that method run separately.
Launch a Timer, when 10 seconds elapsed, check the status of the first thread.
If it has fetched all that he was supposed to, make use of that, otherwise kill the thread, clean whatever you have to clean and return that message of error.
Related
I have created a trigger web job for some web application call, but I got a requirement that trigger job customer should be able to start or stop when want, and can also schedule.
I have done the schedule part using webjobs rest API but I am not able to complete start and stop work as trigger job does not have any option.
Is there a way to start and stop trigger webjob. I have tried to use kudo kill process but after webjob trigger completes it does not appear in process explorer.
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes($"{azureUserName}:{azurePassword}"));
if (string.Equals(jobStatus, "STOP", StringComparison.InvariantCultureIgnoreCase))
{
using(var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Auth);
//var baseUrl = new Uri($"https://{webAppName}.scm.azurewebsites.net/");
var requestURl = string.Format("{0}/api/processes", azureWebAppUrl);
var response = client.GetAsync(requestURl).Result;
if (response.IsSuccessStatusCode == true)
{
string res = response.Content.ReadAsStringAsync().Result;
var processes = JsonConvert.DeserializeObject < List < ProcessData >> (res);
if (processes.Any(x => x.name.Contains(azureWebJobName)))
{
requestURl = string.Format("{0}/api/processes/{1}", azureWebAppUrl, processes.Where(x => x.name.Contains(azureWebJobName)).FirstOrDefault().id);
response = client.DeleteAsync(requestURl).Result;
}
returnStr = "success";
}
else
{
returnStr = response.Content.ToString();
}
}
}
Please help me to understand a better way to stop and start the trigger web job process. I also found that we can add app settings to the main application like WEBJOBS_STOPPED and WEBJOBS_DISABLE_SCHEDULE but it will depend and need to update it every time, I want to rely on webjob setting completely instead of main application settings.
I do not know if I understand your problem or not.
I think, You can use Quartz(1) for start job/jobs and schedule it with application setting.
https://www.quartz-scheduler.net/
I have a method that executes several HTTP requests called LoadServers() A button that executes LoadServers(). For my issue I only tap the button once the previous LoadServers() call has finished. A progress dialog appears while loading so I can only execute them serially.
Once in about every 10-15 calls to LoadServers results in the first http request to delay for almost exactly 10 seconds. The average time for LoadServers to complete is less than a half second and never more than 1 second. This only happens on Xamarin.Android. The delay does not happen on Xamarin.iOS and all of this code is shared.
Here is my code
private async Task LoadServers() {
await Get();
await Post();
await Get();
await Get();
await Post();
}
private async Task Get() {
var url = _httpClient.BaseAddress + model.GetToken();
Log("Attempting to send GET to: " + url);
using (var response = await _httpClient.GetAsync(url))
{
var resultContent = await response.Content.ReadAsStringAsync();
Log("Got response back from : " + url + ": " + resultContent);
}
}
private async Task Post() {
var content = requestData.GetToken() + "=" + requestData.PostBody ();
var request = new StringContent(content)
{
Headers = { ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded") }
};
var url = _httpClient.BaseAddress + "/No_content";
Log ("Attempting to send POST to: " + url + " with content: " + content);
using (var response = await _httpClient.PostAsync(url, request))
{
string resultContent = await response.Content.ReadAsStringAsync();
Log("Got response back from : " + url + ": " + resultContent);
}
}
Every 15 or so executions of LoadServers() results in the following log statements:
Thread started: #37
Thread finished: #37
[2017-01-21T13:42:30.8841620-06:00] [debug] Loading Servers
[2017-01-21T13:42:30.8946770-06:00] [debug] Attempting to send GET to: XXX
Thread finished: <Thread Pool> #23
Thread started: <Thread Pool> #38
[2017-01-21T13:42:40.9550360-06:00] [debug] Got response back from : XXX <-- Notice the time (~10 seconds)
Does this have to do with resource consumption for the HTTP request? It attempts to clean up the resources and pauses execution until that happens? I'm not sure exactly what happens when it execute the request. Does it start a new thread?
Figuring out the exact issue is tough, and I'm unable to reproduce it. However, the wrapping of System.Net and the default MessageHandler in the HttpClient is not completely optimized. So, your guess at it being a resource issue could be the case.
Try using ModernHttpClient (Xamarin Component | Nuget | Developer Review | Github), and adding the NativeMessageHandler in the constructor for you HttpClient. This will use the some optimized native libraries (for Android, it's OkHttp) which will help with performance.
I experimented the same issue.
i'm using xamarin.android 6.6.1.2-21 and support stuff for Api 23.
I found that using the default httpHandler and creating 2 httpClients before your first call solve this issue.
new HttpClient( new Xamarin.Android.Net.AndroidClientHandler());
and create 2 httpclients before start any real call in your code.
Also setup the "HttpClient implementation" to "AndroidClientHandler". You can find this option on: Project options > Android build > Code generation And Runtime.
This only work on android 5+
http implementation option
I'm building a SOCKS proxy checker using .NET 4.5 and everything works fine except when one of SOCKS proxies is really slow and it takes over 100 seconds to respond. I'd like to timeout those proxies at few stages (ConnectAsync, ReadToEndAsync) especially at ReadToEndAsync because if proxy is slow it hangs.
I've tried everything I was able to find about this, using Cancellation tokens, Task.Wait, NetworkStream.ReadTimeout ( doesn't work.. strange )..
and if I use Task.Wait then I can't use await keyword which makes it synchronous and not async and that beats the whole idea of my tool..
var socksClient = new Socks5ProxyClient(IP,Port);
var googleAddress = await Dns.GetHostAddressesAsync("google.com");
var speedStopwatch = Stopwatch.StartNew();
using(var socksTcpClient = await socksClient.CreateConnection(googleAddress[0].ToString(),80))
{
if(socksTcpClient.Connected)
{
using(var socksTcpStream = socksTcpClient.GetStream())
{
socksTcpStream.ReadTimeout = 5000;
socksTcpStream.WriteTimeout = 5000; //these don't work..
using (var writer = new StreamWriter(socksTcpStream))
{
await writer.WriteAsync("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n");
await writer.FlushAsync();
using (var reader = new StreamReader(socksTcpStream))
{
var result = await reader.ReadToEndAsync(); // up to 250 seconds hang on thread that is checking current proxy..
reader.Close();
writer.Close();
socksTcpStream.Close();
}
}
}
}
}
Shamefully, async socket IO does not support timeouts. You need to build that yourself. Here is the best approach I know:
Make your entire function not care about timeouts. Disable all of them. Then, start a delay task and when it completes dispose of the socket. This kills all IO that is in flight and effects immediate cancellation.
So you could do:
Task.Delay(TimeSpan.FromSeconds(100)).ContinueWith(_ => socksTcpClient.Dispose());
This leads to an ugly ObjectDisposedException. This is unavoidable.
Probably, you need to cancel the delay in case of success. Otherwise you keep a ton of delay tasks for 100 seconds and they might amount to millions depending on load.
I have created a simple experiment in Azure ML and trigger it with an http client. In Azure ML workspace, everything works ok when executed. However, the experiment times out and fails when I trigger the experiment using an http client. Setting a timeout value for the http client does not seem to work.
Is there any way we can set this timeout value so that the experiment does not fail?
Make sure you're setting the client timeout value correctly. If the server powering the web service times out, then it will send back a response with the HTTP status code 504 BackendScoreTimeout (or possibly 409 GatewayTimeout). However, if you simply never receive a response, then your client isn't waiting long enough.
You can find out a good amount of time by running your experiment in ML Studio. Go to the experiment properties to find out how long it ran for, and then aim for about twice that amount of time as a timeout value.
I've had similar problems with an Azure ML experiment published as a web service. Most of the times it was running ok, while sometimes it returned with a timeout error. The problem is that the experiment itself has a 90 seconds running time limit. So, most probably your experiment has a running time over this limit and returns with a timeout error. hth
Looks like it isn't possible to set this timeout based on a feature request that is still marked as "planned" as of 4/1/2018.
The recommendation from MSDN forums from 2017 is to use the Batch Execution Service, which starts the machine learning experiment and then asynchronously asks whether it's done.
Here's a code snippet from the Azure ML Web Services Management Sample Code (all comments are from their sample code):
using (HttpClient client = new HttpClient())
{
var request = new BatchExecutionRequest()
{
Outputs = new Dictionary<string, AzureBlobDataReference> () {
{
"output",
new AzureBlobDataReference()
{
ConnectionString = storageConnectionString,
RelativeLocation = string.Format("{0}/outputresults.file_extension", StorageContainerName) /*Replace this with the location you would like to use for your output file, and valid file extension (usually .csv for scoring results, or .ilearner for trained models)*/
}
},
},
GlobalParameters = new Dictionary<string, string>() {
}
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
// WARNING: The 'await' statement below can result in a deadlock
// if you are calling this code from the UI thread of an ASP.Net application.
// One way to address this would be to call ConfigureAwait(false)
// so that the execution does not attempt to resume on the original context.
// For instance, replace code such as:
// result = await DoSomeTask()
// with the following:
// result = await DoSomeTask().ConfigureAwait(false)
Console.WriteLine("Submitting the job...");
// submit the job
var response = await client.PostAsJsonAsync(BaseUrl + "?api-version=2.0", request);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
string jobId = await response.Content.ReadAsAsync<string>();
Console.WriteLine(string.Format("Job ID: {0}", jobId));
// start the job
Console.WriteLine("Starting the job...");
response = await client.PostAsync(BaseUrl + "/" + jobId + "/start?api-version=2.0", null);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
string jobLocation = BaseUrl + "/" + jobId + "?api-version=2.0";
Stopwatch watch = Stopwatch.StartNew();
bool done = false;
while (!done)
{
Console.WriteLine("Checking the job status...");
response = await client.GetAsync(jobLocation);
if (!response.IsSuccessStatusCode)
{
await WriteFailedResponse(response);
return;
}
BatchScoreStatus status = await response.Content.ReadAsAsync<BatchScoreStatus>();
if (watch.ElapsedMilliseconds > TimeOutInMilliseconds)
{
done = true;
Console.WriteLine(string.Format("Timed out. Deleting job {0} ...", jobId));
await client.DeleteAsync(jobLocation);
}
switch (status.StatusCode) {
case BatchScoreStatusCode.NotStarted:
Console.WriteLine(string.Format("Job {0} not yet started...", jobId));
break;
case BatchScoreStatusCode.Running:
Console.WriteLine(string.Format("Job {0} running...", jobId));
break;
case BatchScoreStatusCode.Failed:
Console.WriteLine(string.Format("Job {0} failed!", jobId));
Console.WriteLine(string.Format("Error details: {0}", status.Details));
done = true;
break;
case BatchScoreStatusCode.Cancelled:
Console.WriteLine(string.Format("Job {0} cancelled!", jobId));
done = true;
break;
case BatchScoreStatusCode.Finished:
done = true;
Console.WriteLine(string.Format("Job {0} finished!", jobId));
ProcessResults(status);
break;
}
if (!done) {
Thread.Sleep(1000); // Wait one second
}
}
}
I am using the .NET 4.5 HttpClient class to make a POST request to a server a number of times. The first 3 calls run quickly, but the fourth time a call to await client.PostAsync(...) is made, it hangs for several seconds before returning the expected response.
using (HttpClient client = new HttpClient())
{
// Prepare query
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("?arg=value");
// Send query
using (var result = await client.PostAsync(BaseUrl + queryBuilder.ToString(),
new StreamContent(streamData)))
{
Stream stream = await result.Content.ReadAsStreamAsync();
return new MyResult(stream);
}
}
The server code is shown below:
HttpListener listener;
void Run()
{
listener.Start();
ThreadPool.QueueUserWorkItem((o) =>
{
while (listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var context = c as HttpListenerContext;
try
{
// Handle request
}
finally
{
// Always close the stream
context.Response.OutputStream.Close();
}
}, listener.GetContext());
}
});
}
Inserting a debug statement at // Handle request shows that the server code doesn't seem to receive the request as soon as it is sent.
I have already investigated whether it could be a problem with the client not closing the response, meaning that the number of connections the ServicePoint provider allows could be reached. However, I have tried increasing ServicePointManager.MaxServicePoints but this has no effect at all.
I also found this similar question:
.NET HttpClient hangs after several requests (unless Fiddler is active)
I don't believe this is the problem with my code - even changing my code to exactly what is given there didn't fix the problem.
The problem was that there were too many Task instances scheduled to run.
Changing some of the Task.Factory.StartNew calls in my program for tasks which ran for a long time to use the TaskCreationOptions.LongRunning option fixed this. It appears that the task scheduler was waiting for other tasks to finish before it scheduled the request to the server.