Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blocking calls but do not block thread

Tags:

c#

winforms

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!

like image 465
user1755712 Avatar asked Sep 05 '13 14:09

user1755712


People also ask

Will blocking a thread block the entire process?

If one user level thread performs blocking operation then entire process will be blocked. If one kernel thread perform blocking operation then another thread can continue execution.

What is the difference between blocking calls and non-blocking calls?

Blocking vs non-blockingBlocking call waits for the I/O operation to complete before returning. Its results are returned synchronously. Nothing else in that process takes place during the waiting. In contrast, non-blocking call returns immediately without results and uses alternate means to check for completion.

What does blocking a thread do?

Blocked means execution gets stuck there; generally, the thread is put to sleep by the system and yields the processor to another thread. When a thread is blocked trying to acquire a mutex, execution resumes when the mutex is released, though the thread might block again if another thread grabs the mutex before it can.

Does asynchronous mean non-blocking?

The send, receive, and reply operations may be synchronous or asynchronous. A synchronous operation blocks a process till the operation completes. An asynchronous operation is non-blocking and only initiates the operation.


1 Answers

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.

like image 59
Scott Chamberlain Avatar answered Sep 28 '22 03:09

Scott Chamberlain