Blocking calls but do not block thread - c#

Recently I came across a proprietary third-party library and there is a method behave in this way:
public Point ClickOnDrawMat(DrawMat drwmat)
{
Point pt;
//waiting user mouse click on DrawMat and assign to pt
return pt;
}
When my code calling this method from main thread, it will block on this method until user clicks, then get the point return from ClickOnDrawMat.
public void button1_Click(object sender, EventArgs e)
{
Point userClickedPoint = ClickOnDrawMat(oDrwMat); //Wait until user clicked
//Do stuff with point we got
}
However, it doesn't block the main thread. I still can press other button/UI control while it is still waiting for user click.
I noticed that upon waiting for user click, one of the CPU core usage seems pretty high (~75%).
And this is an example of the call stack after I click on another button while it still waiting for user click:
myProgram.frmMain.button2_Click(xxx) Line 23
[External Code]
ThirdPartyLib.ClickOnDrawMat(xxx) Line 16
myProgram.frmMain.button1_Click(xxx) Line 14
I am wondering how can this be done?
Thanks in advance!

We can't tell you exactly how it is done unless somone had a copy of the library and they use a decomplier to see what the code is doing (if you want to do it yourself dotPeek is free and easy to use).
However by how you describe its behavior it is likely repeatedly calling Application.DoEvents() inside the function, this will let other messages be processed while the long running process is doing it's thing.
This is almost never a good coding practice for polling operations due to its high CPU cost, as you noticed, I recommend not doing it in your own code.
The "correct" way to handle this is use one of the Asynchronous Programming Patterns: the async/await feature added in .NET 4.5 or as a NuGet package for 4.0 (TAP), have the library raise an event of its own (EAP), or have the function use a callback function when it is finished (APM). Inside the function itself it should use a event driven system internally so that it does not use CPU power while it is waiting for an event to happen instead of polling.

Related

What happens when async code attempts to resume on a thread that is already executing?

I feel that the answer to this is due to me having an incorrect concept of how threads work, but here goes.
private void button1_Click(object sender, EventArgs e)
{
this.TestMethodAsync(); // No await, i.e. fire and forget
// ** Some code here to perform long running calculation (1) **
}
private async Task TestMethodAsync()
{
// Some synchronous stuff
await Task.Delay(1000);
// ** Some code here to perform long running calculation (2) **
}
First of all, I would not "fire and forget" an asynchronous method like this (I would use Task.Run) but I've come across code that does, and I'm trying to understand what the effect is.
In a WinForms application, which uses a WindowsFormsSynchronizationContext, my understanding of async and await tells me that when I click button1, the method will start synchronously on the UI thread. It will call TestMethodAsync and run synchronously until it reaches the await. It will then capture the context, start the Task.Delay task, and yield control to the caller. Since we are not awaiting this call, button1_Click will continue on the UI thread and start performing calculation (1).
At some point, Task.Delay(1000) will complete. A continuation will then run the remainder of the TestMethodAsync method using the captured context, which in this case means that the continuation will be run on the UI thread. This will now start performing calculation (2).
We now have two separate sections of code wanting to run on the same thread (the UI thread) at the same time. My investigations into this seem to suggest that the thread switches back and forth between the two sections of code in order to perform them both.
QUESTION:
I'm confused about exactly what is going on here. How is it possible to resume on a thread that is already running other code? What forces the thread to switch between the two sections of code that want to run? In general, what happens when you attempt to resume on a thread that is already running some other code?
(I suppose this isn't any different to how my click event runs on the UI thread in the first place, in as much as I know it runs on the UI thread, and I know the UI thread is also doing other stuff, but I've not really thought about it like this before.)
This is the secret that you do not understand: I give you the Windows Message Loop
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
while(TRUE)
{
bRet = GetMessage(&msg, NULL, 0, 0);
if (bRet <= 0) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
This is the actual "main" of your application; you just don't see it because it is hidden behind the scenes.
A simpler loop could not be imagined. It gets a message from the queue. If there are no more messages then the program must be done. If there was a message then it runs the standard message translations and dispatches the message, and then keeps on running.
How is it possible to resume on a thread that is already running other code?
It isn't. "Resuming on a thread that is running other code" is actually putting a message in the queue. That "other code" is being synchronously called by DispatchMessage. When it is done, it returns to the loop, the queue is polled, and the message indicates what code needs to be dispatched next. That then runs synchronously until it returns back to the loop.
What forces the thread to switch between the two sections of code that want to run?
Nothing. That doesn't happen.
In general, what happens when you attempt to resume on a thread that is already running some other code?
The message that describes what continuation needs to be run is queued up.
I suppose this isn't any different to how my click event runs on the UI thread in the first place, in as much as I know it runs on the UI thread, and I know the UI thread is also doing other stuff, but I've not really thought about it like this before.
Start thinking about it.
Click events are exactly the same. Your program is doing something; you click the mouse; the click hander does not interrupt the UI thread and start running new work on it. Rather, the message is queued up, and when your UI thread control returns to the message loop, the click is eventually processed; DispatchMessage causes Button1_OnClick to be invoked via some mechanism in Windows Forms. That's what WinForms is; a mechanism for translating Windows messages into calls to C# methods.
But you already knew that. You know that when an event-driven program does a long-running synchronous operation, that the UI freezes, but that click events are processed eventually. How did you think that happened? You must have understood at some level that they were being queued up for processing later, right?
Exercise: What does DoEvents do?
Exercise: Given what you now know: what could possibly go wrong if you call DoEvents in a loop to unblock your UI?
Exercise: How is await different from DoEvents in a GUI application?
How is it possible to resume on a thread that is already running other code?
It needs to be specifically designed to support it. There needs to be some framework in place that allows the thread to take in work and to then execute that work at some later point in time.
This is how your UI thread works. It has a queue, and whenever you schedule work to be done in the UI thread you add an item to the end of the queue. The UI thread then takes the first item from the queue, executes it, and then when it's done, goes on to the next item, and so on, until you end your application.
What forces the thread to switch between the two sections of code that want to run?
Nothing, because it doesn't do that. It runs one, then when it finishes, it runs the other.
In general, what happens when you attempt to resume on a thread that is already running some other code?
Either someone wrote some custom code to specifically do just that, in which case, it does whatever that code specifically told it to do, or else you can't.

How to call Same event Handler with multiple class object in Windows form C# [duplicate]

I have a windows forms application
on which I need to use a for loop having a large number of Remote Calls around 2000 - 3000 calls,
and while executing the for loop, I loose my control on form and form controls, as it becomes a large process and some time it shows "Not Responding" but if I wait for a long it comes back again, I think I need to use some threading model for that, is there any idea, how can I proceed to solve the issue?
You need to perform the long running operation on a background thread.
There are several ways of doing this.
You can queue the method call for execution on a thread pool thread (See here):
ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
In .NET 4.0 you can use the TaskFactory:
Task.Factory.StartNew(() => YourMethod());
And in .NET 4.5 and later, you can (and should, rather than TaskFactory.StartNew()) use Task.Run():
Task.Run(() => YourMethod());
You could use a BackgroundWorker for more control over the method if you need things like progress updates or notification when it is finished. Drag the a BackgroundWorker control onto your form and attach your method to the dowork event. Then just start the worker when you want to run your method. You can of course create the BackgroundWorker manually from code, just remember that it needs disposing of when you are finished.
Create a totally new thread for your work to happen on. This is the most complex and isn't necessary unless you need really fine grained control over the thread. See the MSDN page on the Thread class if you want to learn about this.
Remember that with anything threaded, you cannot update the GUI, or change any GUI controls from a background thread. If you want to do anything on the GUI you have to use Invoke (and InvokeRequired) to trigger the method back on the GUI thread. See here.
private voidForm_Load(object sender, EventArgs e)
{
MethodInvoker mk = delegate
{
//your job
};
mk.BeginInvoke(callbackfunction, null);
}
private void callbackfunction(IAsyncResult res)
{
// it will be called when your job finishes.
}
use MethodInvoker is the easiest way.
Obviously, you need to use background threads. I suggest you read this free e-book.

The best way to wait for a UI control?

I have a UserControl at which a message is being appeared gradually and after a few seconds it'll be faded again. This control uses a backgroundWorker. It works all right. But I should add an overload for the method which is responsible for showing the message as:
ShowMessage(string message, bool waitToHide) { .. }
Now, I need to know what the best way to make calling thread (the UI thread) wait for the above method is.
I tried to raise an event to notify the invoking scope that the inside backgroundWorker has completed, but since this method has been used frequently in the main application, I must break many unified scopes into some scattered ones.
{
// before code snippet..
messageDisplayer1.ShowMessage("test", true);
// after code snippet..
}
will turn to:
{
// before..
messageDisplayer1.ShowMessage("test", true);
}
void messageDisplayer1_Done()
{
// after..
}
If you have to stick with .NET 3.5 or .NET 4 without the async CTP, I don't think you will be able to avoid splitting your code (unless you want to litter your code with DoEvents, which is definitely not recommended).
On the other hand, the async extensions (either the CTP for .NET 4 or the version included in .NET 4.5) allow you to do something like this:
{
// before code snippet..
await messageDisplayer1.ShowMessage("test", true);
// after code snippet..
}
Then the compiler automatically puts your "after code snippet" into a separate code block (a continuation), which is run as soon as ShowMessage has signaled completion. In the mean time, control is returned to the Windows message loop, leaving your program's UI responsive.

Threading in Form_Load - Application now hangs suddenly

Sorry for the lengthy post, I just want to illustrate my situation as best as possible. Read the items in bold and check the code if you want the quick gist of the issue.
I use ClickOnce to deploy a C# application, and have opted to have my application check for updates manually using the ApplicationDeployment Class rather than letting it do the update checking for me.
The program is a specialized network scanner that searches for network devices made by the company I work for. Once the main window is loaded, a prompt is displayed asking if the user would like to scan the network. If they say Yes, a scan begins which can take a minute or two to complete depending on their network settings; otherwise it just waits for the user to do some action.
One of the last things I do in Form_Load is create a new thread that checks for updates. This had all been working fine for several months through about 12 releases and has suddenly stopped working. I didn't change the update code at all, nor change the sequence of what happens when the app starts.
In staring at the code, I think I see why it is not working correctly and wanted to confirm if what I think is correct. If it is, it begs the question as to why it DID work before - but I'm not too concerned with that either.
Consider the following code:
frmMain.cs
private void Form1_Load(object sender, EventArgs e)
{
// set up ui, load settings etc
Thread t = new Thread(new ParameterizedThreadStart(StartUpdateThread));
t.Start(this);
}
private void StartUpdateThread(object param)
{
IWin32Window owner = param as IWin32Window;
frmAppUpdater.CheckForUpdate(owner);
}
frmAppUpdater.cs
public static void CheckForUpdate(IWin32Window owner)
{
if (ApplicationDeployment.IsNetworkDeployed) {
Console.WriteLine("Going to check for application updates.");
parentWindow = owner;
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
ad.CheckForUpdateCompleted += new CheckForUpdateCompletedEventHandler(ad_CheckForUpdateCompleted);
ad.CheckForUpdateProgressChanged += new DeploymentProgressChangedEventHandler(ad_CheckForUpdateProgressChanged);
ad.CheckForUpdateAsync();
// CAN/WILL THE THREAD CREATED IN FORM1_LOAD BE TERMINATED HERE???
}
}
When the CheckForUpdateAsync() callback completes, if no update is available the method call simply returns; if an update IS available, I use a loop to block until 2 things occur: The user has dismissed the "Would you like to scan prompt" AND no scan is currently running.
The loop looks like this, which takes place in ad_CheckForUpdateCompleted:
while (AppGlobals.ScanInProgress || AppGlobals.ScanPromptVisible) {
System.Threading.Thread.Sleep(5000);
}
I sleep for 5 seconds because I figured this was happening in a separate thread and it has seemed to work well for a while.
My main question about the above code is:
When ad.CheckForUpdateAsync(); is called from CheckForUpdate does the thread I created in Form1_Load terminate (or might it terminate)? I suspect it may because the subsequent Async call causes the method to return, and then start another thread?
The only reason I am confused is because this method WAS working for so long without hanging the application and now all of the sudden it hangs and my best effort at debugging revealed that it was that Sleep call blocking the app.
I'd be happy to post the full code for frmAppUpdater.cs if it would be helpful.
When ad.CheckForUpdateAsync(); is called from CheckForUpdate does
the thread I created in Form1_Load terminate (or might it terminate)?
If the CheckForUpdateAsync() call is asynchronous then yes, the thread will terminate, no it won't otherwise.
If you suspect the Sleep to have caused the application hang then these two variables AppGlobals.ScanInProgress and AppGlobals.ScanPromptVisible are probably always set to true! You should start looking at the code that is setting them to true and see what is going on there.
In order to avoid an application hang, you could introduce a variable to avoid sleeping indefinitely:
int nTrials = 0;
while ((AppGlobals.ScanInProgress || AppGlobals.ScanPromptVisible) && (nTrials < 5)) {
System.Threading.Thread.Sleep(5000);
nTrials++;
}
// Check the results and act accordingly
I personally do not like using Sleep for thread synchronization. .NET offers a bunch of classes that are perfect for thread synchronization, WaitHandle being one of them.
See this post at Asynchronous Delegates Vs Thread/ThreadPool?
your form load method seems to be doing synchronous work. you mention that you are using clickonce deployment. Has the binary location changed after the previous release or has permissions on this resource changed. Looks like the work (checkupdates) in the Thread is never finishing and is never handed back to the form.
as an immediate fix, I would change the Thread approach to Delegate - if you use delegate, then this becomes less of a customer issue (the form will respond to end user) but the underlying problem remains.
as the next step, i would go through http://msdn.microsoft.com/en-us/library/ms229001.aspx and do the troubleshoot

Asynchronous API for Streaming Data from a Hardware Device

I'm writing a library in C#, but I need to make it asynchronous. Normally you expose a set of DLL functions, and they take input parameters, and return a value when finished. But how can I make a library function (callable from C++/Delphi/Etc) that already starts streaming back output while still taking input?
The only solution I see now is to communicate using sockets/pipes/etc, instead of DLL calls.
Does someone have an example how to do this with normal DLL calls?
One good model for a straightforward asynchronous library call (which is located in System.dll) is WebClient.DownloadStringAsync. This method downloads from a Uri asynchronously, and raises the DownloadStringCompleted event whenever it finishes.
Your library could likewise provide a FooAsync method, which doesn't block the current thread but raises a FooDataReceived event whenever some data comes into your library and a FooCompleted event whenever the calculation finishes.
According to the comments from the OP the calling application sends audio to the DLL, the DLL sends audio out via some USB interface, the DLL captures some audio from the mic interface and needs to send the captured audio back to the application while the application sends audio to the DLL etc.
Based on this and the fact that the calling can be written in rahter different languages I see some options for the communication channels:
TCP/IP (depending on "desktop firewall settings" etc. this could be problematic!)
Pipes
COM objects with events/event handlers
DLL with callback although this will be a bit hard to get working for all languages
shared memory with global mutexes (could ease that for the consuming application by offering a "setup" function from the DLL which return the pointers and mutex names)
There are a couple of ways to go with this. In most languages you can make async calls to methods using threads or dispatchers. In general, as long as you make your dll re-entrant (capable of servicing multiple threads at the same time) the calling environment can take care of the async part.
It is possible to bake the async calls into your API, however. An example of something that does this is the WCF client proxies.
Microsoft has a good article on this matter. If you just mover over the EndInvoke, it should work for you as well. http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.71).aspx
Since you want both Input and Output to be async, you will need a
worker thread: If neither the inputting thread, nor the one taking
the output can be blocked, both can't be bothered to do the work.
Your already thought of communicating via pipes, but why use a pipe and not an internal strcuture?
So you have this lock-free queue on the input, another one on the output and a worker thread
The worker thread takes input from the inqueue, processes it, puts it into the outqueue
If the input queue becomes empty, the worker thread has nothing to crunch on, so he raises a "need more data" event and then blocks on the input queue becoming (partly) full
If the worker thread puts something in the output queue, he raises a "have more data" event, and if the output queue becomes (fully) full, he blocks on output space becoming available
Your API is nonblocking: Neither sending input nor receiving output ever block
Your API is async: Notifications (via Events) are given
I like the following approach because it makes it really simple for the clients.
// your library
class Foo {
public event EventHandler ComputeCompleted = (sender, e) => { };
public void Compute() {
// kick off work on a background thread
// possibly using the BackgroundWorker object
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += RunWorkerCompleted;
bw.RunWorkerAsync();
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
ComputeCompleted(this, new object());
}
}
// calling code
Foo foo = new Foo();
foo.ComputeCompleted += Completed;
foo.Compute();
private void Completed(object Sender, EventArgs e) {
// process the result here
}
The gist is that you kick off a method in the library that returns right away, then notifies the caller via an event/delegate that the processing is complete. You are then free to Invoke the execution back onto the UI thread as needed.
Obviously, error handling not included in the sample code.

Categories

Resources