Reputation: 53
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!
Upvotes: 5
Views: 117
Reputation: 127583
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.
Upvotes: 7