Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何跨线程获取control.Handle属性_C#_Multithreading - Fatal编程技术网

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

C# 如何跨线程获取control.Handle属性,c#,multithreading,C#,Multithreading,我是并行编程新手,在尝试绘制测量结果时,我遇到了一个臭名昭著的错误“从创建它的线程以外的线程访问控件名” 经过几个小时的网络浏览和失败的实验,我不得不放弃并寻求建议 我试图做的是在程序继续执行时,在一个单独的线程中进行一些绘图 在绘图例程(在面板控件上)中,我非常广泛地使用API调用(Polyline、BitBlt等),其中我必须使用IntPtr hDCh_Dst=Win32.GetDC(pnlSchermo.Handle) 我在网上找到了数千个解决这个问题的建议方案(几乎都是用于设置属性的,还

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

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

我试图做的是在程序继续执行时,在一个单独的线程中进行一些绘图

在绘图例程(在面板控件上)中,我非常广泛地使用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...
}
do
{
//数据采集与处理。。。
//等等。。。
//绘制测量结果。。。
线程thrDisegna=新线程(()=>disignagrafico(NcF:NcZxF));
thrDisegna.Start();
//做一些其他的处理。。。
//等待打印作业结束:
while(thrDisegna.IsAlive);
}
while(bMisuraOn);
私有void disignagrafico(字符串HcTipo=”“,int NcF=0)
{
//一些初始化。。。
//调用类QL(即类Quadro的实例)中的方法XY来缩放pnlSchermo控件,并进行一些API绘图:
QL.XY(pnlSchermo,…,参考hdcDst,…);
//其他一些API绘图使用hdcDst。。。
}
公共空间XY(面板pnlSchermo,…,参考IntPtr hdcDst,…)
{
// ...
//这里是我需要使用pnlSchermo.Handle的地方:
hDCh_Dst=Win32.GetDC(pnlSchermo.Handle);//已解决

越来越多的时间浏览网页给了他们的果实

Control.Invoke挂起应用程序时出现的问题是由于Invoke的交叉干扰(在返回之前等待其完成),以及主线程在:

while(thrDisegna.IsAlive)

将这一行替换为:

do{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(…)继续返回零

再见,下一个


Franco

当异常告诉您您做错了时,明智的做法是停止做错。您可以在工作线程中“打印”到位图。完成后,您可以将其显示在窗口中。这正是我所做的:我在位图上打印缩放的分划板,然后在其上添加测量曲线(多段线)但是,在最后,我必须把它放到面板控制上,这里是我需要控制的地方。把手放在手边。谢谢你的回答。