I have a method that utilises SendKeys.Send, waits for a few seconds using System.Threading.Thread.Sleep and then runs another method to check the colour of a pixel to see if it has changed. The method then runs again as it is called recursively.
This method needs to be able to run thousands of times before stopping. The Winform's UI seems to stop responding when this is running.
I tried to implement a background worker to take the strain off of the UI. I moved the recursive method's code over to the Do_Work event and called it with RunWorkerAsync but it crashed, reporting the following:
An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code
Additional information: SendKeys cannot run inside this application because the application is not handling Windows messages.
What's the best way of moving the code away from the UI? I'm not very familiar with background workers so I may be doing it wrong.
Sounds like a case for async. Try replacing Thread.Sleep() with Task.Delay().
async void Button_Click(object sender, RoutedEventArgs e)
{
await SendMyKeysAsync();
}
async Task SendMyKeysAsync()
{
while (thePixelIsStillRed)
{
SendKeys.Send("whatever");
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
This approach leaves the UI thread free to continue pumping messages during the delay period, without spawning any additional threads.
Rather than a synchronous recursive method, you should write an asynchronous iterative method.
private async void Foo()
{
while(ShouldKeepLooping())
{
SendKeys.Send(keyToSend);
await Task.Delay(timespan.FromSeconds(2));
}
}
Making the method recursive adds nothing; making it iterative removes stack pressure. By making the method asynchronous, rather than synchronous, you don't block the UI thread.
Related
I would like to stop a method until a custom delegate provides a callback from one method to a listener in another in Xamarin.Android, but I am having a lot of trouble understanding the implementation of such a listener.
I have only tried to understand how this could be done, but I'm stuck on how the delegate would be constructed and called.
Let's say that I want this MainActivity method to stop
public async override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
//how can I create a listener to stop this method until callback from OnPause?
//await a delegate task?
}
and await another method inside a Fragment:
public override void OnResume()
{
base.OnResume();
//I'd like to implement a delegate here to notify the OnWindowFocusChanged that OnResume method has been invoked
//what would be the construction of such?
}
How could I do that?
From my research, I believe I would need to create a delegate task, and then await it's return in OnWindowFocusChanged. However, I am confused about the implementation of such a solution. If anyone could provide even a very basic pseudo-code example, it would help me out a lot.
EDIT: I changed OnPause to OnResume because that's more useful for understanding what I'm trying to do. The below answer references OnPause, but those two are extremely similar methods anyway.
Here is an example that almost does what I'm trying to do; except instead of starting my method when OnResume is invoked, OnWindowFocusChanged stops for 10000ms. So basically, I'd like to replace the timer with a custom delegate (similar to an event) task that returns when Fragment.OnResume is invoked.
public async override void OnWindowFocusChanged(bool hasFocus)
{
base.OnWindowFocusChanged(hasFocus);
//we won't pass this line for 10000ms; how to replace with Task return?
await WaitHere();
}
async Task WaitHere()
{
System.Threading.Thread.Sleep(10000);
}
You could try Task.Run method like:
await Task.Run(() => OnPause());
This would basically create a new thread or use the one you are on and schedule everything after this line as a continuation. So yes, the method would kinda stop, but unless you are on some GUI thread (not to block) or you run some IO task this is unnecessary.
I do not really understand what you are trying to achieve, but you might try to create new OnPauseAsync method that would return Task to get some result from the method when it finishes. This way you would get sequential like mechanism that doesn't block.
If you want to run those methods truly in parallel, but stop execution of OnWindowFocusChanged unitl something hapens in OnPause you should use bare Threads and some synchronization primitives like Mutex or Barrier. Then you would be able to make "main" thread wait until something happens (but it would block! beware). About those fellas you can read more here : LINK_WITH_FOCUS_ON_BARRIER
I am not really sure I got your intentions right, but I hope it helps somehow in the end.
To review:
if you just want to wait for the completion of OnPause and it does only CPU heavy things and you are not on UI thread - do not do anything as there is no profit in using threads etc.
if onPause does some IO heavy things you can use:
Tasks - potentially executed on one thread and doesn't block, control is returned to OnWindowFocusChanged AFTER onPause finishes completely.
Threads - if you want to run some parallel (two threads guaranteed) computations and wait for onPause to signal AT SOME POINT of execution to its caller that it might proceed, you can use e.g Barrier - but beware as this is the most complex solution from programmers perspective and it blocks if you are on UI thread.
I have read a lot of articles and still cant get understand this part.
Consider this code :
private async void button1_Click(object sender, EventArgs e)
{
await Dosomething();
}
private async Task<string> Dosomething()
{
await Task.Run((() => "Do Work"));
return "I am done";
}
First question:
When I click the button, it will Call DoSomething and await a Task that creates a Thread from the threadpool by calling Task.Run ( if I am not mistaken ) and all of this runs asynchronously. So I achieved creating a thread that does my work but doing it asynchronously? But consider that I don't need any result back, i just want the work to be done without getting any result back, is there really a need to use async/await , and if so, how?
Second question:
When running a thread asynchronously, how does that work? Is it running on the main UI but on a separate thread or is it running on a separate thread and separate is asynchronously inside that method?
The purpose of creating Async methods is so you can Await them later. Kind of like "I'm going to put this water on to boil, finish prepping the rest of my soup ingredients, and then come back to the pot and wait for the water to finish boiling so I can make dinner." You start the water boiling, which it does asynchronously while you do other things, but eventually you have to stop and wait for it. If what you want is to "fire-and-forget" then Async and Await are not necessary.
Simplest way to do a fire and forget method in C#?
Starting a new task queues that task for execution on a threadpool thread. Threads execute in the context of the process (eg. the executable that runs your application). If this is a web application running under IIS, then that thread is created in the context of the IIS worker process. That thread executes separately from the main execution thread, so it goes off and does its thing regardless of what your main execution thread is doing, and at the same time, your main execution thread moves on with its own work.
1
There's a big difference if you don't await the Task or you await it:
Case you don't await it: DoSomething is called but next sentence is executed while DoSomething Task hasn't been completed.
Case you await it: DoSomething is called and next sentence is executed once DoSomething Task has been completed.
So, the need of async/await will depend on how you want to call DoSomething: if you don't await it is like calling it the fire & forget way.
2
Is it running on the main UI but on a separate thread or is it running
on a seperate thread and separate is asynchronously inside that
method?
Asynchronous code sometimes means other thread (see this Q&A Asynchronous vs Multithreading - Is there a difference?). That is, either if the code is being executed in a separate thread from the UI one or it lets continue the processing of the UI thread while it gets resumed, it's nice because UI loop can still update the screen while other tasks are being done in parallel without freezing the UI.
An asynchronous method (i.e. async method) is a syntactic sugar to tell the compiler that await statements should be treated as a state machine. The C# compiler turns your async/await code into a state machine where code awaiting a Task result is executed after the code that's being awaited.
Interesting Q&As
You might want to review these other Q&As:
Async/Await vs Threads
What's the difference between Task.Start/Wait and Async/Await?
async/await - when to return a Task vs void?
Is Async await keyword equivalent to a ContinueWith lambda?
OP said...
[...] But does this mean that "async/await" will fire off a thread and
Task.Run also fires off a thread or are they both the same thread?
Using async-await doesn't mean "I create a thread". It's just a syntactic sugar to implement continuations in an elegant way. A Task may or may not be a thread. For example, Task.FromResult(true) creates a fake task to be able to implement an async method without requirement it to create a thread:
public Task<bool> SomeAsync()
{
// This way, this method either decides if its code is asynchronous or
// synchronous, but the caller can await it anyway!
return Task.FromResult(true);
}
The type Task<TResult> requires you to return a TResult from your task. If you don't have anything to return, you can use Task instead (which, incidentally, is the base class of Task<TResult>).
But keep in mind that a task is not a thread. A task is a job to be done, while a thread is a worker. As your program runs, jobs and workers become available and unavailable. Behind the scenes, the library will assign your jobs to available workers and, because creating new workers is a costly operation, it will typically prefer to reuse the existing ones, through a thread pool.
I'm using Parallel.ForEach for the first time, where I'm processing files; in the context of a WinForms app.
As per guidance from other threads on this coding problem (Parallel.ForEach progress reporting) I have a public (int) counter property on my class which contains the parallel code, and it's successfully updating; I also have a Timer on my Form that periodically reads the counter.
The issue is that when I execute the parallel code the visible progress updating appears to stop, and then starts as soon as the parallel code is complete.
FYI - I'm calling the parallel code directly - that is, not through a background worker or async method.
Parallel.ForEach actually evaluates the query in parallel fashion but does wait for finishing of execution and blocks the calling thread.
You should use it on a separate thread/backgroundworker/task to get your progress variable updating while not blocking the UI.
If you are calling Parallel.ForEach() from your UI thread (lacking a code example, there's no way for us to know for sure what's happening), then the fact that that method stops and waits for all the processing to complete will prevent your UI thread from doing any other work, including a) allowing the timer event from being processed, and b) allowing the UI to be updated even if the timer even were processed.
One possible approach would be to wrap the call of Parallel.ForEach() in a call to Task.Run(). For example:
private async void button1_Click(object sender, EventArgs e)
{
// some stuff
await Task.Run(() => Parallel.ForEach(...));
// some other stuff
}
Alternatively, you could just execute the whole thing as individual tasks:
private async void button1_Click(object sender, EventArgs e)
{
// some stuff
List<Task> tasks = new List<Task>();
foreach (...)
{
tasks.Add(Task.Run(() => ...));
}
await Task.WhenAll(tasks);
// some other stuff
}
(The above examples leave out specifics, since without a code example in the question there's no way to know what would actually go there).
Either approach should free up your UI thread to handle the progress updating while the processing goes on.
I've been working on a client application that connects to a server asynchronously using the async and await keywords. I am trying to asynchronously call a method with an infinite loop that checks for an internet connection every few seconds. Here is the initial code for when I start the connection.
private async void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "Connect")
{
button1.Enabled = false;
await ConnectClient();
await Task.Run(() => CheckForInternet());
//Doesn't execute past this line
button1.Enabled = true;
}
...
}
Here is the what my CheckForInternet() method does
private async Task CheckForInternet()
{
while (true)
{ //Close out of the method when done checking
if (stopCheckingForInternet)
return;
//If there is internet
if (InternetGetConnectedState())
{
...
}
//If an internet connection was lost
else
{
...
}
}
}
I want the CheckForInternet() method to have its own individual thread after I call it with the ability to not block, but without the need to use the Thread class. I tried out the method used at
http://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html
In other words, is there a way to start a thread using these methods asynchronously and then after the thread starts, can control be returned back to the context in which it was called?
The asynchronous call blocks and it will not get past it unless it is completely terminated. I want to have the thread stay running indefinitely but also be able to return to the lines below the one where I call this asynchronous method instead of blocking and never allowing the lines below the call to be executed.
You shouldn't use async/await in this scenario. "await" will make your method block. You should use just a Task.StartNew() for your CheckForInternet method (or other suitable way of creating a Task).
Inside CheckForInternet I think it's a good idea to put a "Thread.Sleep()" inside it, to avoid unnecessary CPU consumption.
Creating a Task automatically creates an internal thread.
Async/await makes much for sense if used for unblocking I/O.
You could choose not to await the task returned by Task.Run; that would make your loop independent.
However, I would recommend that you either have a top-level try/catch within CheckForInternet, or save the returned Task and respond appropriately when it completes.
I'm having an issue with a WinRT project. Currently the execution on the program is running on two threads. One thread executes the main application and the other handles the UI side of things. At the moment, I'm having an issue calling a function from the main thread to execute on the UI thread, waiting for a reply and then continuing execution on the main thread... let me show you some code as an example.
public async void SignOut(Action onSuccess, Action onFailure)
{
bool success = false;
bool wait = true;
CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await SignOutAsync();
success = true;
wait = false;
});
while (wait) { }
if (success)
{
onSuccess();
}
else
{
onFailure();
}
}
So this code is doing what I want it to do but it's obviously not the right way to go about it with the busy waiting and all of that. The problem is that if I move the OnSuccess/OnFailure execution into the RunAsync lambda then there is an error on the callback about invalid memory because the execution is on a different thread. Currently the problem I'm facing is that I can't remove the busy wait without screwing up the order of execution. Ideally I want to wait for the entire RunAsync lambda to finish execution on the UI thread and then return to the main thread to run the success/fail callbacks.
It appears at the moment that as soon as I hit the await SignOutAsync() part of the RunAsync lambda the RunAsync task marks itself as complete and returns to the Success/Failure check before the SignOutAsync method has any result. I believe this is due to the nested async methods and that you can't really await on the RunAsync call and then again on the async lambda within it.
Any advice would be greatly appreciated.
Currently the execution on the program is running on two threads. One thread executes the main application and the other handles the UI side of things.
This is not ideal. If at all possible, structure your code so that you only have one "special" thread (the UI thread). async allows your UI thread to remain responsive without requiring a second "special" thread.
At the moment, I'm having an issue calling a function from the main thread to execute on the UI thread, waiting for a reply and then continuing execution on the main thread.
Again, a better design is to have your program logic provide "services" to the UI, instead of the other way around. So, do your best to redesign the calls so that the UI is driving the program logic and not the opposite.
That said, if you absolutely must have a single "special" background thread, you can use the AsyncContextThread type from my AsyncEx library. AsyncContextThread understands asynchronous methods, so you can do this:
public async Task SignOutAsync(Action onSuccess, Action onFailure)
{
try
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => SignOutAsync());
onSuccess();
}
catch
{
onFailure();
}
}
However, I would be embarrassed to put this code into production; anything that uses Dispatcher is a code smell. Even though I wrote the AsyncContextThread type, I can't recommend it for Windows Store projects. A far better design is to structure the code so that the program logic never calls back into the UI.