从单独的线程/类设置Control属性

时间:2014-02-16 18:11:51

标签: c# multithreading class listbox

我已经搜索过,无法找到一个解决方案,可以帮助我从一个单独的类中运行的线程中获取文本,返回到创建该线程的表单上的列表框。

基本上我有一个持有“测试”的类,它从测试窗口调用它自己的线程。我希望能够做的是将文本添加到主窗体上的列表框中,以便让用户知道测试的内容。我在Invoke上可以找到的所有示例都显示了如何在同一个类中完成它。

我在哪里开始主题:

    PermeabilityTest Run_Test = new PermeabilityTest();
    public Thread WorkerThread;

    private void button2_Click(object sender, EventArgs e)
    {
        //enable timer for test duration display
        timer1.Enabled = true;

        //create and start new thread.
        WorkerThread = new Thread(Run_Test.RunTest);
        WorkerThread.Start();
    }

这是我的课程实际完成的工作,我需要在单独的表单上将文本返回到列表框。

public class PermeabilityTest
{
    //volatile alerts the compiler that it will be used across threads.
    private volatile bool aborted;

    public void RequestStop()
    {
        //handle saving data file here as well.
        aborted = true;
    }

    public void RunTest()
    {
        //reference the comms class so we can communicate with the machine
        PMI_Software.COMMS COM = new COMMS();

        //some test stuffs here
        int x = 0;
        while( x < 100 && !aborted)
        {
            System.Diagnostics.Debug.Write("Well here it is, running it's own thread." + Environment.NewLine);
            COM.Pause(1);
        }  
    }        
}

我很感激任何能帮助我理解如何将一些文本带回到具有启动帖子的按钮的同一表单上的列表框的人。

1 个答案:

答案 0 :(得分:0)

选项1 :(已暂存) PermeabilityTest 上添加活动,并在主表单中注册该活动。 然后在主窗体中修改列表框的内容。

示例:

您的主要表格:

    PermeabilityTest Run_Test = new PermeabilityTest();
    public Thread WorkerThread;

    public form1()
    {
        // Register on the Progress event
        Run_Test.Progress += Run_Test_Progress;
    }

    void Run_Test_Progress(string message)
    {
    if(listBox.InvokeRequired)
        {
            // Running on a different thread than the one created the control
            Delegate d = new ProgressEventHandler(Run_Test_Progress);
            listBox.Invoke(d, message);
        }
        else
        {
            // Running on the same thread which created the control
            listBox.Items.Add(message);
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        //enable timer for test duration display
        timer1.Enabled = true;

        //create and start new thread.
        WorkerThread = new Thread(Run_Test.RunTest);
        WorkerThread.Start();
    }

新代表:

    public delegate void ProgressEventHandler(string message);

修改PermeabilityTest类:

    public class PermeabilityTest
    {
        //volatile alerts the compiler that it will be used across threads.
        private volatile bool aborted;
        public event ProgressEventHandler Progress;

        public void RequestStop()
        {
            //handle saving data file here as well.
            aborted = true;
        }

        public void RunTest()
        {
            //reference the comms class so we can communicate with the machine
            PMI_Software.COMMS COM = new COMMS();

            //some test stuffs here
            int x = 0;
            while (x < 100 && !aborted)
            {
                // Report on progress
                if(Progress != null)
                {
                    Progress("This message will appear in ListBox");
                }
                System.Diagnostics.Debug.Write("Well here it is, running it's own thread." + Environment.NewLine);
                COM.Pause(1);
            }
        }
    }

选项2: 您可以将 PermeabilityTest 作为主窗体的内部类,并通过这样做,允许它访问主窗体的私有成员。 然后,您需要将主窗体的引用传递给 PermeabilityTest 的构造函数,并将其保留为成员。

选项3: 将列表框传递给 PermeabilityTest

的构造函数

不要忘记在控件上使用Invoke,因为您从另一个线程运行。