Background Agent notifyComplete() after HTTPRequest - c#

I want to create an HTTPRequest on a periodic task in a windows phone 7 background agent.
To keep it simple I just want to call a method on a shared class between the backgroundAgent and the application.
The shared method is a simple HTTPRequest.
On the SharedClass.cs makeTheRequest()
public static void makeTheRequest(){
var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
request.BeginGetResponse(r =>
{
NotifyComplete();
}, request);
}
I cannot call the notifyComplete() here because is not in the scope.
On the BackgroundAgent.cs onInvoke()
protected override void OnInvoke(ScheduledTask task)
{
if (task is PeriodicTask)
{
SharedClass.makeTheRequest();
NotifyComplete();
}
}
When I call it here, probably makeTheRequest() never gets done because the process is killed before it gets completed
I have read something about Taks Parallel library, but I don't know if thas is the right way to do it nor how to do it.
thanks

I'd change your makeTheRequest() method so that you can pass it an Action to fire upon request completion.
In the call from the agent you can include the call to NotifyComplete() but from the app you don't do this.
Note also that you should include timeout handling in the agent as repeated failing of the request from within the agent, due to timing out, can lead to the agent being disabled.
Update
An Example:
protected override void OnInvoke(ScheduledTask task)
{
if (task is PeriodicTask)
{
SharedClass.makeTheRequest(this.NotifyComplete);
}
}
public class SharedClass
{
public static void makeTheRequest(Action callback)
{
var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
request.BeginGetResponse(r => callback.Invoke(), request);
}
}

Once the main bgAgent thread exits, the HttpWebRequest will be killed.
We should be using synchronous HttpWebRequest here, but we can't because MS took them away from gelded framework.
We have to mimic thread-blocking behaviour using thread synchronization objects, like
ManualResetEvent.
protected override void OnInvoke(ScheduledTask task)
{
var evnt = new ManualResetEvent(false);//initialize to unsignalled state (false)
var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
request.BeginGetResponse(r =>
{
//do work here
evnt.Set();//signal main thread to continue
}, request);
evnt.WaitOne();//block execution of main thread
NotifyComplete();
return;
}
This way neither main thread will exit not NotifyComplete will be called before you finish your work.
You should make that WaitOne with a timeout (around 25 seconds) to ensure your task won't get killed and (worse) unsheduled because of 30 secs limit. This will make things much more complicated, as you'll have to protect your both threads (main and http) from messing each other up.
The evnt.Close() issue is also not shown here. Main thread may close the handle before http finishes and tries to Set(). Or you can rely on garbage collection Do I need to call Close() on a ManualResetEvent?
(btw, ManualResetEvent has nothing to do with concept of C# event. It's and event in Win32 sense, from same gang as Mutex and Semaphore).

You MUST use Delegate
In SharedClass.cs
public delegate void MyDelegate();
public MyDelegate MyUpdate;
In BackgroundAgent.cs
Maybe
void UpdateLiveTile() { ..... NotifyComplete(); }
In BackgroundAgent.cs onInvoke()
var cs = new SharedClass();
cs.MyUpdate= new SharedClass.MyDelegate(UpdateLiveTile);
cs.makeTheRequest();
In public static void makeTheRequest()
public static void makeTheRequest()
{
var request ....
request.BeginGetResponse(r =>
{
.........
MyUpdate();
}, request

Related

Call to WebAPI does not return correctly with Async

I have created a Service which runs on a Client. This Service inserts a Log Entry in a Database on Server. The Log entry is inserted via API which is running on Server. Below is the simplified code inside Service1 class. The Service is Timer based and runs repeatedly when needed. Hence, it needs to insert the Log Entry when needed. i.e. SendToServer() function is executed repeatedly. I have remove the Timer code because it is not relevant here.
public class Logs
{
public string param1 { get; set; }
public string param2 { get; set; }
}
static HttpClient client = new HttpClient();
System.Timers.Timer timer = new System.Timers.Timer(); //New Edit
protected override void OnStart(string[] args)
{
SendToServer();
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);//New Edit
timer.Interval = 60000; //New Edit
timer.Enabled = true; //NewEdit
}
private void OnElapsedTime(object source, ElapsedEventArgs e)//New Edit
{
SendToServer();
}
public void SendToServer()
{
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync(EventLogEntry Log)
{
client.BaseAddress = new Uri("https://<IP>:<Port>/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Logs log = new Logs
{
param1 = "value1";
param2 = "value2";
};
var url = await CreateLogsAsync(log);
}
static async Task<Uri> CreateLogsAsync(Logs log)
{
ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
};
HttpResponseMessage response = await client.PostAsync("api/Logs", new StringContent(new JavaScriptSerializer().Serialize(log), Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
return response.Headers.Location;
}
When I install the service or power up the Client Machine. The first database insert works fine. However, the data is not inserted in the database the second time. When I restart the system it again inserts the first log. I sense that there is problem with ASync Functions and the first call to API never returns correctly after inserting the data.
The similar code works perfectly in Console Application.
The problem is that your Windows Service is shutting down after executing this line:
RunAsync().GetAwaiter().GetResult();
The OnStart() method needs to do something that keeps the service running, or it will shutdown when OnStart() returns. However, you can't put a perpetual loop, like while (true), in the OnStart() method because the system calls OnStart() as a callback to your code, and it expects OnStart() to return in a timely manner. Likewise, starting a Task or initiating anything on the ThreadPool won't work (as you've seen) because these run as background threads, and background threads are stopped automatically when the application stops. From the link:
A thread is either a background thread or a foreground thread.
Background threads are identical to foreground threads, except that
background threads do not prevent a process from terminating. Once all
foreground threads belonging to a process have terminated, the common
language runtime ends the process. Any remaining background threads
are stopped and do not complete.
To solve the problem, you need to start a foreground thread. Here's a very rough example that should solve the immediate problem. You'll need tweak it to do what you want it to do.
using System.Threading;
public sealed class MyService : ServiceBase
{
private Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
protected override void OnStart(string[] args)
{
// Create the thread object and tell it to execute the Run method
_thread = new Thread(Run);
// Name the thread so it is identifyable
_thread.Name = "MyService Thread";
// Set the thread to be a foreground thread (keeps the service running)
_thread.IsBackground = false;
// Start the thread
_thread.Start();
}
protected override void OnStop()
{
// Set the shutdown event to tell the foreground thread to exit
// the while loop and return out of the Run() method
_shutdownEvent.Set();
// Wait for the foreground thread to exit
_thread.Join();
}
private void Run()
{
// The while loop keeps the foreground thread active by executing
// over and over again until Stop() sets the shutdown event, which
// triggers the while loop to exit.
while (!_shutdownEvent.WaitOne(1000))
{
// Put your logic here.
RunAsync().GetAwaiter().GetResult();
}
}
}
Note that the while loop in the Run() method will run over and over again until the shutdown event is set (see the Stop() method). The argument to the WaitOne() call is in milliseconds. As coded, the WaitOne() call will block for 1 second before executing your code again. You'll need to tweak this so that your code runs when you want it to.
HTH

Is there a way to abort a thread and then open it again with a new variable?

I want to open a thread to do the things it needs to do until a new command is given by the user. Then this thread should either close or receive a new command.
I have seen many posts that sending a variable to a running thread is hard, that is why I decided to kill the thread and start it again with the new variable.
I used the following post: https://stackoverflow.com/a/1327377 but without success. When I start the thread again (after it has done abort()) it gives me an exception: System.Threading.ThreadStateException.
private static Thread t = new Thread(Threading);
private static bool _running = false;
static void Main(string[] args)
{
[get arg]
if (CanRedo(arg))
{
if (t.IsAlive)
{
_running = false;
t.Interrupt();
if (t.Join(2000)) // with a '!' like in the post, abort() would not be called
{
t.Abort();
}
}
_running = true;
t.Start(arg); // gives System.Threading.ThreadStateException
}
}
private static void Threading(object obj)
{
_stopped = false;
string arg = obj.ToString();
while(_running)
{
if (bot._isDone)
{
ExecuteInstruction(arg);
}
}
}
What am I doing wrong?
I'm going to guess that you don't literally mean to abort the thread and start that same thread again. That's because if we start a thread to do some work we don't care which thread it is. If you cancel one thing and start something else, you probably don't care if it's the same thread or a different one. (In fact it's probably better if you don't care. If you need precise control over which thread is doing what then something has gotten complicated.) You can't "abort" a thread and restart it anyway.
Regarding Thread.Abort:
The Thread.Abort method should be used with caution. Particularly when you call it to abort a thread other than the current thread, you do not know what code has executed or failed to execute when the ThreadAbortException is thrown, nor can you be certain of the state of your application or any application and user state that it is responsible for preserving. For example, calling Thread.Abort may prevent static constructors from executing or prevent the release of unmanaged resources.
It's like firing an employee by teleporting them out of the building without warning. What if they were in the middle of a phone call or carrying a stack of papers? That might be okay in an emergency, but it wouldn't be a normal way to operate. It would be better to let the employee know that they need to wrap up what they're doing immediately. Put down what you're carrying. Tell the customer that you can't finish entering their order and they'll need to call back.
You're describing an expected behavior, so it would be better to cancel the thread in an orderly way.
That's where we might use a CancellationToken. In effect you're passing an object to the thread and telling it to check it from time to time to see if it should cancel what it's doing.
So you could start your thread like this:
class Program
{
static void Main(string[] args)
{
using (var cts = new CancellationTokenSource())
{
ThreadPool.QueueUserWorkItem(DoSomethingOnAnotherThread, cts.Token);
// This is just for demonstration. It allows the other thread to run for a little while
// before it gets canceled.
Thread.Sleep(5000);
cts.Cancel();
}
}
private static void DoSomethingOnAnotherThread(object obj)
{
var cancellationToken = (CancellationToken) obj;
// This thread does its thing. Once in a while it does this:
if (cancellationToken.IsCancellationRequested)
{
return;
}
// Keep doing what it's doing.
}
}
Whatever the method is that's running in your separate thread, it's going to check IsCancellationRequested from time to time. If it's right in the middle of doing something it can stop. If it has unmanaged resources it can dispose them. But the important thing is that you can cancel what it does in a predictable way that leaves your application in a known state.
CancellationToken is one way to do this. In other really simple scenarios where the whole thing is happening inside one class you could also use a boolean field or property that acts as a flag to tell the thread if it needs to stop. The separate thread checks it to see if cancellation has been requested.
But using the CancellationToken makes it more manageable if you want to refactor and now the method executing on another thread is a in separate class. When you use a known pattern it makes it easier for the next person to understand what's going on.
Here's some documentation.
What about doing it this way:
private static Task t = null;
private static CancellationTokenSource cts = null;
static void Main(string[] args)
{
[get arg]
if (CanRedo(out var arg))
{
if (t != null)
{
cts.Cancel();
t.Wait();
}
// Set up a new task and matching cancellation token
cts = new CancellationTokenSource();
t = Task.Run(() => liveTask(arg, cts.Token));
}
}
private static void liveTask(object obj, CancellationToken ct)
{
string arg = obj.ToString();
while(!ct.IsCancellationRequested)
{
if (bot._isDone)
{
ExecuteInstruction(arg);
}
}
}
Tasks are cancellable, and I can see nothing in your thread that requires the same physical thread to be re-used.

What is the best practice for running multiple background tasks

I have a Windows Service (.NET 4.5.2) which should run multiple tasks in the background while I want to use the System.Threading.Tasks which of the following implementation you are considering best practice? Or am I completely wrong?
Scenario 1:
protected override void OnStart(string[] args)
{
// Assume all tasks implemented the same way.
// I believe we shouldn't await the tasks in this scenario.
var token = this._cancellationTokenSource.Token;
this.RunTask1(token);
this.RunTask2(token);
this.RunTask3(token);
}
private async Task RunTask1(CancellationToken token)
{
var telebot = new Telebot("SOMETHING");
while( true )
{
// Some work...
// I/O dependent task.
var response = await telebot.GetUpdatesAsync(cancellationToken: token);
//
// Some other work
// maybe some database calls using EF async operators.
//
await Task.Delay(TimeSpan.FromSeconds(1), token);
}
}
Scenario 2:
protected override void OnStart(string[] args)
{
// Assume all tasks implemented the same way.
// I believe we shouldn't await the tasks in this scenario.
var token = this._cancellationTokenSource.Token;
this.RunTask1(token);
this.RunTask2(token);
this.RunTask3(token);
}
private void RunTask1(CancellationToken token)
{
Task.Factory.StartNew(async () =>
{
var telebot = new Telebot("SOMETHING");
while( true )
{
// Some work...
// I/O dependent task.
var response = await telebot.GetUpdatesAsync(cancellationToken: token);
//
// Some other work
// may be some database calls using EF async operators.
//
await Task.Delay(TimeSpan.FromSeconds(1), token);
}
}, token);
}
I cannot explain which is best one but here is how things work
in 1. scenario code till await keyword is executed by parent Thread i.e. main thread of application. So once execution await task execution completed thing handled by context which is saved i.e. main thread context.
in 2. scenario code it started running on thread which is created by Task Factory. here once execution await task execution completed things handled by parent i.e Thread created by Task Factory.
So in the first scenario is good if you want to post something to main thread mostly to UI of application. Second scenario is good if you want to run thing in background and doesnt need of parent context i.e. main thread or UI thread.
An async method runs synchronously until the first await. After that it will run on a ThreadPool thread (unless there's a SynchronizationContext).
So, using Task.Factory.StartNew or Task.Run is discouraged as it's trying to parallelize something which is mostly already parallel.
If, however, you have a substantial synchronous part it can be useful using Task.Run (which is preferable to Task.Factory.StartNew) to parallelize it, but you should do it when calling the method and not in the method itself.
So, "Scenario 1" is better than "Scenario 2".
I would though that you shouldn't fire and forget these operations. You should store the tasks, wait for them to complete and observe any exceptions inside them, for example:
protected override void OnStart()
{
var token = _cancellationTokenSource.Token;
_tasks.Add(RunTask1(token));
_tasks.Add(RunTask2(token));
_tasks.Add(Task.Run(() => RunTask3(token))); // assuming RunTask3 has a long synchronous part
}
List<Task> _tasks;
protected override void OnStop()
{
_cancellationTokenSource.Cancel();
Task.WhenAll(_tasks).Wait();
}

Wrap method with callback delegate inside Task [duplicate]

I'm writing a networked application.
Messages are sent over the transport as such:
Network.SendMessage (new FirstMessage() );
I can register an event handler to be called when this message type arrives, like so:
Network.RegisterMessageHandler<FirstMessage> (OnFirstMessageReceived);
And the event gets fired:
public void OnFirstMessageReceived(EventArgs<FirstMessageEventArgs> e)
{
}
I'm writing a custom authentication procedure for my networked application, which requires around five messages to complete.
Without using the Task Parallel Library, I would be forced to code the next step of each procedure in the preceding event handler, like so:
public void OnFirstMessageReceived(EventArgs<FirstMessageEventArgs> e)
{
Network.SendMessage( new SecondMessage() );
}
public void OnSecondMessageReceived(EventArgs<SecondMessageEventArgs> e)
{
Network.SendMessage( new ThirdMessage() );
}
public void OnThirdMessageReceived(EventArgs<ThirdMessageEventArgs> e)
{
Network.SendMessage( new FourthMessage() );
}
public void OnFourthMessageReceived(EventArgs<FourthMessageEventArgs> e)
{
// Authentication is complete
}
I don't like the idea of jumping around the source code to code a portion of this and a portion of that. It's hard to understand and edit.
I hear the Task Parallel Library substantially simplifies this solution.
However, many of the examples I read using the Task Parallel Library were related to starting a chain of active tasks. What I mean by 'active', is that each task could start when called explicitly, like so:
public void Drink() {}
public void Eat() {}
public void Sleep() {}
Task.Factory.StartNew( () => Drink() )
.ContinueWith( () => Eat() )
.ContinueWith( () => Sleep() );
This is opposite from my event-based async pattern, in which each event handler method is called only when the message is received.
In other words, I can't do something like this (but I want to):
Task.Factory.StartNew( () => OnFirstMessageReceived() )
.ContinueWith( () => OnSecondMessageReceived() )
.ContinueWith( () => OnThirdMessageReceived() )
.ContinueWith( () => OnFourthMessageReceived() );
I've read this article, but I don't quite understand it. It seems like what I need has to do with TaskCompletionSource. If I wanted to make a task from my event-based async pattern like the code block above, what would it look like?
You're right about TaskCompletionSource, it's the key to transforming EAP (event-based asynchronous pattern) to TPL's Task.
This is documented here: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/tpl-and-traditional-async-programming#exposing-complex-eap-operations-as-tasks
Here is the simplified code:
public static class Extensions
{
public static Task<XDocument> GetRssDownloadTask(
this WebClient client, Uri rssFeedUri)
{
// task completion source is an object, which has some state.
// it gives out the task, which completes, when state turns "completed"
// or else it could be canceled or throw an exception
var tcs = new TaskCompletionSource<XDocument>();
// now we subscribe to completed event. depending on event result
// we set TaskCompletionSource state completed, canceled, or error
client.DownloadStringCompleted += (sender, e) =>
{
if(e.Cancelled)
{
tcs.SetCanceled();
}
else if(null != e.Error)
{
tcs.SetException(e.Error);
}
else
{
tcs.SetResult(XDocument.Parse(e.Result));
}
};
// now we start asyncronous operation
client.DownloadStringAsync(rssFeedUri);
// and return the underlying task immediately
return tcs.Task;
}
}
Now, all you need to do, to make a chain of those operations, is just to set your continuations (which is not very comfortable at the moment, and the C# 5 await and async will help alot with it)
So, this code could be used like this:
public static void Main()
{
var client = new WebClient();
client.GetRssDownloadTask(
new Uri("http://blogs.msdn.com/b/ericlippert/rss.aspx"))
.ContinueWith( t => {
ShowXmlInMyUI(t.Result); // show first result somewhere
// start a new task here if you want a chain sequence
});
// or start it here if you want to get some rss feeds simultaneously
// if we had await now, we would add
// async keyword to Main method defenition and then
XDocument feedEric = await client.GetRssDownloadTask(
new Uri("http://blogs.msdn.com/b/ericlippert/rss.aspx"));
XDocument feedJon = await client.GetRssDownloadTask(
new Uri("http://feeds.feedburner.com/JonSkeetCodingBlog?format=xml"));
// it's chaining - one task starts executing after
// another, but it is still asynchronous
}
Jeremy Likness has a blog entry title Coroutines for Asynchronous Sequential Workflows using Reactive Extensions (Rx) that might interest you. Here is the question he tries to answer:
The concept is straightforward: there are often times we want an asynchronous set of operations to perform sequentially. Perhaps you must load a list from a service, then load the selected item, then trigger an animation. This can be done either by chaining the completed events or nesting lambda expressions, but is there a cleaner way?

Proxy or FiddlerCore

I'm trying to write a program that catches the HTTP get requests.
I have found Fiddler-core a genius library that should do exactly what I want.
The thing is, I'm trying to execute a big piece code-work inside the void FiddlerApplication_BeforeRequest(Session oSession) and it seems to block all the request and damage my surfing speed a great deal.
I have tried to use threads/tasks with no avail.
What am I doing wrong?
This is my code:
public event RequestCapture RequestCaptured;
private CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
//...stat public function:
public void RunWatch() {
Fiddler.FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
Fiddler.FiddlerApplication.Startup(0, FiddlerCoreStartupFlags.Default);
}
void FiddlerApplication_BeforeRequest(Session oSession)
{
if (RequestCaptured != null)
{
CancellationToken ct = cancelTokenSource.Token;
Task.Factory.StartNew(() =>RequestCaptured(oSession.fullUrl), ct);
//Handle the event in a new thread, so the Listener will continue to listen
}
}
//close public function:
public void Close() {
try
{
FiddlerApplication.Shutdown();
cancelTokenSource.Cancel();
}
catch { }
}
now i have i different class that do that:
public Form1()
{
Listiner = new HttpWatcher.Listner();
Listiner.RequestCaptured += RequestCaptured;
Listiner.RunWatch();
}
void RequestCaptured(string url)
{
System.Threading.Thread.Sleep(10000);
}
edit
The question is: Is there a better way using fiddler-core? or am i to build a simple proxy for that? using something else? Thanks!
edit2
I have edited the code, so it would fill the missing parts.
Just to be clear here, FiddlerCore processes each Session on a threadpool thread. If you need blocking behavior, there's no need to spin up an additional thread or anything like that. If you don't need to process things in a blocking manner, then feel free to queue the data on a background queue and use tasks or another asynchronous mechanism to perform processing.
You should explain exactly what you mean when you say damage my surfing speed a great deal, and whether or not you see different behavior when using Fiddler rather than your application.

Categories

Resources