gpt4 book ai didi

c# - 如何跨线程获取 control.Handle 属性

转载 作者:太空宇宙 更新时间:2023-11-03 15:54:24 25 4
gpt4 key购买 nike

我是并行编程的新手,在尝试绘制测量结果时,我遇到了臭名昭著的错误“控制控件名称从创建它的线程以外的线程访问。” .

经过几个小时的网页浏览和失败的实验,我不得不放弃并寻求建议。

我想做的是在程序继续执行的同时在单独的线程中进行一些绘图。

在绘图例程中(在面板控件上)我使用了相当广泛的 API 调用(Polyline、BitBlt 等...),其中我必须使用 IntPtr hDCh_Dst = Win32.GetDC(pnlSchermo.Handle)。

我在网上找到了数以千计的针对此问题的建议解决方案(几乎全部用于设置属性,少数用于获取),但我无法使它们正常工作。

这是我目前正在 WFA 项目中测试的(简化的)代码。

do
{
// Data acquisition and processing...
// etc...

// Plot the measurement results...
Thread thrDisegna = new Thread(() => DisegnaGrafico(NcF: NcZxF));
thrDisegna.Start();

// Do some other processing...

// Wait for the end of the plot job:
while (thrDisegna.IsAlive);

}
while (bMisuraOn);

private void DisegnaGrafico(string HcTipo = "", int NcF = 0)
{
// Some initialisations...

// Call the method XY in the Class QL (that is an instance of the Class Quadro) for scaling the pnlSchermo control and do some API plot:
QL.XY(pnlSchermo, ..., ..., ref hdcDst, ..., ...);

// Some other API plotting using the hdcDst...
}

public void XY(Panel pnlSchermo, ..., ..., ref IntPtr hdcDst, ..., ...))
{
// ...

// Here is where I need to use the pnlSchermo.Handle:
hDCh_Dst = Win32.GetDC(pnlSchermo.Handle); // <-- Fails with the "Control control name accessed ..." exception.

// or... but doesn't work either and the program hangs:
pnlSchermo.Invoke(new MethodInvoker(delegate() { hDCh_Dst = Win32.GetDC(pnlSchermo.Handle); }));

// or... the program doesn't hangs, no exception thrown but returns _hDCh_Dst = 0. Does it need a EndInvoke?
IntPtr _hDCh_Dst = IntPtr.Zero;
pnlSchermo.BeginInvoke(new MethodInvoker(delegate
{
_hDCh_Dst = pnlSchermo.Handle;
}));
hDCh_Dst = Win32.GetDC(_hDCh_Dst);

// or... other solutions found on the Web and tested without success...
}

再见,感谢关注。

佛朗哥

最佳答案

解决了!!

越来越多的网页浏览时间带来了成果!

Control.Invoke 挂起应用程序的问题是由于 Invoke 的交叉干扰,它在返回之前等待其完成,并且主线程在以下位置循环:

同时(thrDisegna.IsAlive);

将这一行替换为:

做 { Application.DoEvents(); } while (thrDisegna.IsAlive);

让以下句柄访问方法起作用:

        IntPtr hDCh_Dst1 = IntPtr.Zero;
pnlSchermo.Invoke(new MethodInvoker(delegate() { hDCh_Dst1 = Win32.GetDC(pnlSchermo.Handle); }));
hDCh_Dst = hDCh_Dst1;

现在,出于好奇,我必须调查为什么 pnlSchermo.BeginInvoke(...) 继续返回零...

再见,下一个。

佛朗哥

关于c# - 如何跨线程获取 control.Handle 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24248352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com