线程保持一个进程,但无用其他

时间:2010-09-04 18:13:09

标签: c# com

大家好,无论客户需要更新旧代码我都有问题。

此代码添加了一个thread.sleep(500)以保持服务处于活动状态,正在从一个com端口读取一些调用,并且当我向相关机器发送一些信息时,此时发送警报到其他PC弹出错误

跨线程操作无效:控制'textBox1'从其创建的线程以外的线程访问。

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
        Thread.Sleep(500);
        string data = port.ReadExisting();
        //try
        //{
            if (textBox1.TextLength == 30000)
            {
                textBox1.Text = "";
            }
        //}
        //catch (Exception) {}
        this.BeginInvoke(new setTextDeleg(si_DataRecived), new object[]{
        data});
    }

这是在com机器上写入的函数,是否正常使用错误,或者还有另一种更好的方法来处理它?<​​/ p> PD:抱歉我的英文不好,这是在C#2008 vs

4 个答案:

答案 0 :(得分:1)

您应该仅从创建它们的线程(主线程)修改GUI组件,如文本框和标签。您可以查看BackgroundWorker,它简化了WinForms应用程序中的此任务。这是另一个useful article,用于说明InvokeRequired属性和Invoke方法的用法。

答案 1 :(得分:0)

简单地吞下这个例外不是一个好主意。发生异常是因为不允许从UI线程(创建它们的线程)以外的任何线程修改UI组件。相反,请查看this MSDN文章,了解如何在工作线程(您的线程休眠)和UI线程之间传递信息,以正确的方式更新文本框。

答案 2 :(得分:0)

问题是因为Windows窗体控件不是线程安全的,并且似乎没有为线程安全调用正确调用控件。您可以使用BackgroundWorker课程,也可以自己invoke。这是一个小代码示例。

    // Delegate used by our worker thread to invoke our control
    private delegate void ProgressDelegate(int value);

    // Callback method used for our delegate
    private void ProgressCallback(int value) {
        progressBar1.Value = value;
    }

    protected override void OnShown(EventArgs e) {
        Thread thread = new Thread(new ThreadStart(MyThreadWorker));
        thread.IsBackground = true;
        thread.Start();
    }

    // Thread method
    private void MyThreadWorker() {
        // Setup the delegate
        ProgressDelegate mydelegate = new ProgressDelegate(ProgressCallback);

        // Do some work
        int pos = 0;
        do {
            pos++;

            // Make a thread-safe call to our control and invoke our callback on the original thread
            // Original thread: The thread the form and control were created on
            progressBar1.Invoke(mydelegate, pos);
        } while (pos < 100);
    }

答案 3 :(得分:0)

我猜你的其他一些代码看起来像什么,但你可能会移动这个

 if (textBox1.TextLength == 30000)
        {
            textBox1.Text = "";
        }

si_DataRecived方法,以便它作为BeginInvoke调用的一部分执行,其目标将在主(UI)线程上执行。