阻止调用但不阻止线程

use*_*712 5 c# winforms

最近我遇到了一个专有的第三方库,并且有一种方法就是这样:

public Point ClickOnDrawMat(DrawMat drwmat)  
{  
    Point pt;
    //waiting user mouse click on DrawMat and assign to pt  
    return pt;  
}
Run Code Online (Sandbox Code Playgroud)

当我的代码从主线程调用此方法时,它将阻止此方法,直到用户单击,然后从中获取点返回ClickOnDrawMat.

public void button1_Click(object sender, EventArgs e)
{
    Point userClickedPoint = ClickOnDrawMat(oDrwMat); //Wait until user clicked
    //Do stuff with point we got
}
Run Code Online (Sandbox Code Playgroud)

但是,它不会阻止主线程.我仍然可以按下其他按钮/ UI控件,同时它还在等待用户点击.
我注意到在等待用户点击时,其中一个CPU核心使用量似乎很高(~75%).

这是我在等待用户点击时点击另一个按钮后调用堆栈的示例:

myProgram.frmMain.button2_Click(xxx) Line 23
[External Code]
ThirdPartyLib.ClickOnDrawMat(xxx) Line 16
myProgram.frmMain.button1_Click(xxx) Line 14
Run Code Online (Sandbox Code Playgroud)

我想知道如何做到这一点?
提前致谢!

Sco*_*ain 7

我们无法确切地告诉你它是如何完成的,除非somone有一个库的副本并且他们使用一个decomplier来查看代码正在做什么(如果你想自己做,dotPeek是免费且易于使用的).

但是,通过如何描述其行为,它可能会Application.DoEvents()在函数内部重复调用,这会让其他消息在长时间运行的过程中处理.

由于CPU成本高,这几乎不是轮询操作的良好编码实践,因为您注意到,我建议不要在您自己的代码中执行此操作.

处理这种情况的"正确"方法是使用异步编程模式之一:在.NET 4.5中添加的async/await功能或作为4.0NuGet包(TAP),让库引发自己的事件(EAP) ,或者让函数在完成时使用回调函数(APM).在函数本身内部,它应该在内部使用事件驱动系统,以便在等待事件发生而不是轮询时不使用CPU电源.