返回首页

大家好,

背景资料:我有一个应用程序,在那里我不断命令发送到微控制器通过串行端口和处理来自串口的反应。我获取和设置不同的控制性能,在此过程中的主要形式。
当我开始这样做的主要过程,我不能点击主窗体上的任何按钮,或选中/取消选中任何复选框,等等等等。我想这是因为一切都在单个线程上运行吗?
所以,现在,我创建了一个单独的线程来执行这个过程中,但我仍然需要更新和从主窗体上的控件的信息。
我的问题是:我需要创建一个"代表"的每一个动作的功能,我在主窗体上的控制上执行,这样做是有一些其他方式。有很多很多东西,我的主要形式,所以它会涉及到创造了大量的委托功能。

任何帮助将不胜感激。

感谢
新手安德烈

下面是一些代码来说明:

protected void start_tests()   //this method runs in its own thread

        {

            string input = string.Empty;

            timer1.Enabled = false;     // this would need delegate?

            if (ResetFlag == true)      //I guess this would need delegate

            {

                reset_selectedindex(); //delegate allready created

                checkedListBox1.SelectedIndex = 0; //this would need delegate

                ResetFlag = false;   //I think this would need delegate

            }

            progressBar1.Maximum = checkedListBox1.CheckedItems.Count;  //this needs delegate

            progressBar1.Value = 0;  //this needs delegate



            while (checkedListBox1_selectedindex() < checkedListBox1_Items_Count())  //delegates used here

            {

                if (checkedListBox1.GetItemCheckState(checkedListBox1.SelectedIndex) == CheckState.Checked)  //delegates needed here

                {

                    UpdateText(checkedListBox1.SelectedItem.ToString() + "\n", UpdateType.TXdata,Color.Lime);  //delegates needed here

                    progressBar1.Value++;   //delegate needed here ....etc etc etc

                    try

                    {

                        show_message_box(checkedListBox1.SelectedIndex,PrePostCommand.precommand);

                        input = ExecCommand("TESTSEQ" + Convert.ToDecimal(checkedListBox1.SelectedIndex).ToString().PadLeft(2, '0') + "\r", 3000, "No responese from OVPT");

                        if (input.Contains("REQUEST"))

                        {

                            if (DialogResult.Yes == show_message_box(checkedListBox1.SelectedIndex,PrePostCommand.postcommand))

                            {

                                UpdateText("TEST:" + Convert.ToDecimal(checkedListBox1.SelectedIndex).ToString().PadLeft(2, '0') + " - " + checkedListBox1.SelectedItem.ToString() + "\r\n", UpdateType.MessageData, Color.Lime);

                                UpdateText("TEST PASS.", UpdateType.MessageData, Color.Lime);

                            }

                            else

                            {

                                UpdateText("TEST:" + Convert.ToDecimal(checkedListBox1.SelectedIndex).ToString().PadLeft(2, '0') + " - " + checkedListBox1.SelectedItem.ToString() + "\r\n", UpdateType.MessageData, Color.Red);

                                UpdateText("TEST FAIL.", UpdateType.MessageData, Color.Lime);

                                TestPass = false;

                            }

 

                        }

                        if (input.Contains("FAIL"))

                        {

                            UpdateText("TEST:" + Convert.ToDecimal(checkedListBox1.SelectedIndex).ToString().PadLeft(2, '0') + " - " + checkedListBox1.SelectedItem.ToString() + "\r\n", UpdateType.MessageData, Color.Red);

                            UpdateText(input, UpdateType.MessageData, Color.Red);

                            TestPass = false;

                        }

                        if (input.Contains("PASS"))

                        {

                            UpdateText("TEST:" + Convert.ToDecimal(checkedListBox1.SelectedIndex).ToString().PadLeft(2, '0') + " - " + checkedListBox1.SelectedItem.ToString() + "\r\n", UpdateType.MessageData, Color.Lime);

                            UpdateText(input, UpdateType.MessageData, Color.Lime);

                        }

                    }

                    catch (Exception e)

                    {

                        UpdateText(e.Message, UpdateType.MessageData,Color.Red);

                        TestPass = false;

                    }

 

                }

                if (checkedListBox1.SelectedIndex == (checkedListBox1.Items.Count - 1))

                {

                    break;

                }

                checkedListBox1.SelectedIndex++;

 

            }

            if (TestPass == false)

            {

                label_Result.Text = "FAILED!!";

                label_Result.BackColor = Color.Red;

                label_Result.ImageIndex = 0;

            }

            else

            {

                label_Result.Text = "PASS!!";

                label_Result.BackColor = Color.Lime;

                label_Result.ImageIndex = 1;

            }

 

            if (checkBox3.Checked == true)

            {

                Thread.Sleep(100);

                button2_Click_1(this, EventArgs.Empty);

                Thread.Sleep(20);

                //start_tests();

            }

            else

            {

                timer1.Enabled = true;

                oThread.Abort();

            }

 

        }

回答

评论会员:游客 时间:2012/02/06
Xeshan艾哈迈德:事件处理程序和Control.Invoke方法(代表)是一个好办法,但如果您使用NET4.0,并没有必要使用的事件,然后使用的SynchronizationContext它是非常容易和简单易用,使用下面的代码对你的主要形式,得到的SynchronizationContext{C}使用此回调来更新您的主要形式的组成部分,从你的线程codeprelang="c#"SendOrPostCallbackcallback=spanclass="code-keyword"delegate/span(spanclass="code-keyword"object/spanobj){spanclass="code-comment"///spanspanclass="code-comment"Updatealltheobjectsherewhichneeddelegate/spancheckedListBox1.SelectedIndex=spanclass="code-digit"0/span;spanclass="code-comment"///spanspanclass="code-comment"nomoreneeddelegate/spanResetFlag=spanclass="code-keyword"false/span;spanclass="code-comment"///spanspanclass="code-comment"nomoreneeddelegate/span};context.Post(callback,spanclass="code-keyword"null/span);/pre/code的
BobJanova
评论会员:游客 时间:2012/02/06
有一些UI和业务逻辑,这里发生了可怕的混合。这是一件好事,你绊倒这种跨线程问题,发现你有所有这些地方,你需要调用,因为它表明了真正的问题NDASH;你想运行测试和你的UI工作在同一个地方,而导致乱码。"所以,现在我创建了一个单独的线程来运行此过程中,但我仍然需要更新,并得到从主窗体上的控件的信息。"不,你不能。你仍然需要得到从数据模型,也被主窗体上显示的信息,你需要能够对信号的进展和完成。运行测试的线程不应该知道任何有关的UI。一般来说,你想要什么像的东西{体C3}那么你的主要形式构建的试运行,输入数据和挂钩的事件。事件处理程序将需要使用Invoke或BeginInvoke,但是这只有3种方法。{的C4}(如果你不使用。NET4,你必须在一个适当的方法或匿名委托调用,而不是这个而整齐的lambda把戏我一会儿回来。)有BackgroundWorkerThread报告进度和完成的测试运行,它可能是可能,但我不知道它获得了很多(这里是非常简单的线程类)