从其他线程访问对象 [英] Access object from other thread

查看:215
本文介绍了从其他线程访问对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想看看这张照片:





我想实例化该控件(这是我的一个面板)到第二个线程。



我的问题是,我发现了很多答案,只是修改一个控件(设置一个文本框的文本),不能读/写它的属性,就像一个对象。 (代表和东西)



我当前的代码:(不工作,因为我在另一个线程中创建了面板)

  public partial class Main:Form 
{
Graphics g;

线程drawCanvasThread;

int pos = 0;

public Main()
{
InitializeComponent();
}

private void Main_Load(object sender,EventArgs e)
{
g = canvas.CreateGraphics();

drawCanvasThread = new Thread(()=> HandleCanvas(canvas));
drawCanvasThread.Start();
}

private void HandleCanvas(Panel objCanvas)
{
面板画布= objCanvas;
点mousePos;
while(true)
{
mousePos = canvas.PointToClient(Cursor.Position);

//更新CANVAS

//绘制CANVAS

Thread.Sleep(17); // 1000/17 ~~ = 60
}
}

private void Main_FormClosing(object sender,FormClosingEventArgs e)
{
drawCanvasThread.Abort );
}
}

PS:线程如何从C#中的另一个线程更新GUI doesn t真的回答我的问题,因为我想要读取对象的属性,而不仅仅是写。虽然这是一个非常有趣的线索。

解决方案

EDITED



您不想将控件实例化到另一个线程。



如果您使用Winforms(Win32)有一些差异, vs WPF(Windows Presentation Foundation)。 Win32 UI库(Winforms)不是线程安全的。如果允许除主UI线程之外的任何线程直接调节控件,您将获得不可预测的结果,内存泄漏和彻底的崩溃。



WPF UI库线程安全,但另一方面仍然有很多问题需要注意,我并不想在这个简短的答案(我希望)中解决这些问题。 ; - )



你真的甚至不希望通过线程边界访问对控件实例的引用。你想要做的是告诉UI线程来做你想要的。有不止一种方式来皮肤那只猫,你会想做一些研究。但是基本思想是您从另一个线程设置某种共享状态,告诉UI线程采取行动,或者提出在UI线程上执行的事件,并启动与该事件处理程序的控件的交互。查看概念,如消息泵。但是你几乎绝对不想做的就是将Windows消息循环转​​化为子类化表单和控件。



其他有用的工具包括 BackgroundWorker 类和较新的任务库。您应该选择一个或另一个,但不能同时使用。一般的模式是,你将从你的UI线程启动一个任务线程,当它返回时,它会在UI线程中引发一个事件,从那里你可以使用窗体上的控件进行有用的工作。


I'm trying to be able to access some controls in my main form from an other thread.

Let's consider this picture:

I want to Instantiate that control (It's a panel in my case) into the second thread.

My problem is that i have found a LOT of answers that just modifies a control (Set the text of a textbox for instance) and not be able to read/write it's properties like it's an object. (Delegates and stuff)

My current code: (Not working because i've created the panel in the other thread)

public partial class Main : Form
{
    Graphics g;

    Thread drawCanvasThread;

    int pos = 0;

    public Main()
    {
        InitializeComponent();
    }

    private void Main_Load(object sender, EventArgs e)
    {
        g = canvas.CreateGraphics();

        drawCanvasThread = new Thread(() => HandleCanvas(canvas));
        drawCanvasThread.Start();
    }

    private void HandleCanvas(Panel objCanvas)
    {
        Panel canvas = objCanvas;
        Point mousePos;
        while(true)
        {
            mousePos = canvas.PointToClient(Cursor.Position);

            //UPDATE CANVAS

            //DRAW CANVAS

            Thread.Sleep(17); //1000 / 17 ~~= 60
        }
    }

    private void Main_FormClosing(object sender, FormClosingEventArgs e)
    {
        drawCanvasThread.Abort();
    }
}

PS: The thread "How to update the GUI from another thread in C#?" doesn't really answers my question, because i want to read the object properties, and not only write. Though it's a very interesting thread.

解决方案

EDITED

You don't want to "instantiate" the control into the other thread.

There are some differences if you're working with Winforms (Win32) vs WPF (Windows Presentation Foundation). The Win32 UI libraries ("Winforms") are not thread-safe. You'll get unpredictable results, memory leaks and outright crashes if you allow any thread other than the main UI thread to directly fiddle with controls.

The WPF UI library is thread-safe, on the other hand, but there are still plenty of issues to be aware of and I'm not trying to address them all in this short (I hope) answer. ;-)

You really don't even want access across a thread boundary to a reference to a control instance. What you want to do is signal the UI thread to do what you want. There's more than one way to skin that cat, and you'll want to do some research. But the basic idea is that you set some kind of shared state from the other thread that tells the UI thread to take action, or raise an event that executes on the UI thread, and you initiate your interaction with the control from that event handler. Look up concepts like a message pump. But what you almost definitely don't want to do is fiddle with the Windows message loop to "subclass" the forms and controls.

Other useful tools include the BackgroundWorker class, and the newer Tasks library. You should pick and use one or the other, but not both simultaneously. The general model is that you'll launch a task thread from your UI thread, and when it returns it will raise an event in the UI thread from where you can do useful work with the controls on your forms.

这篇关于从其他线程访问对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆