阻止调用,但不阻止线程

本文关键字:线程 调用 | 更新日期: 2023-09-27 18:30:22

>最近我遇到了一个专有的第三方库,并且有一种方法可以这样运行:

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

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

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

但是,它不会阻塞主线程。 我仍然可以在等待用户单击时按其他按钮/UI 控件。
我注意到在等待用户单击时,其中一个 CPU 核心使用率似乎相当高 (~75%)。

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

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

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

阻止调用,但不阻止线程

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

但是,通过您描述其行为的方式,它可能会在函数内部重复调用Application.DoEvents(),这将允许在长时间运行的进程执行其操作时处理其他消息。

几乎从来都不是轮询操作的良好编码实践,因为它的 CPU 成本很高,正如您所注意到的,我建议不要在您自己的代码中执行此操作。

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