C# Theads可以维持一个进程,但在其他方面没有用处

C# Theads可以维持一个进程,但在其他方面没有用处,c#,com,C#,Com,大家好,我有一个问题,不管是旧代码还是客户端需要更新 这段代码添加了一个线程。sleep(500)保持服务活动,正在从com端口读取一些调用,并向其他PC发送警报。这次,当我向相关机器发送一些信息时,此错误弹出 跨线程操作无效:控件“textBox1”是从创建它的线程以外的线程访问的 private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { Thread.Sleep(500

大家好,我有一个问题,不管是旧代码还是客户端需要更新

这段代码添加了一个线程。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机器上写入的函数,是否可以创建异常来消除错误,或者是否有其他更好的方法来处理它


PD:很抱歉我的英语不好,这是在C#2008 vs

上,你应该只从创建它们的线程(主线程)修改GUI组件,如文本框和标签。您可以在WinForms应用程序中查看简化此任务的方法。这里还有一个例子说明了属性和方法的用法。

简单地接受这个异常不是一个好主意。发生异常是因为不允许从UI线程(创建UI组件的线程)以外的任何线程修改UI组件。相反,请阅读有关如何在工作线程(休眠的线程)和UI线程之间传递信息以正确方式更新文本框的文章。

问题在于Windows窗体控件不是线程安全的,并且似乎没有为线程安全调用正确调用该控件。您可以使用该类,也可以自己使用。下面是一个小代码示例

    // 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);
    }
//工作线程用于调用控件的委托
私有委托void ProgressDelegate(int值);
//用于委托的回调方法
私有void ProgressCallback(int值){
progressBar1.值=值;
}
显示时受保护的覆盖无效(事件参数e){
线程线程=新线程(新线程开始(MyThreadWorker));
thread.IsBackground=true;
thread.Start();
}
//线程方法
私有void-readworker(){
//设置代理
ProgressDelegate mydelegate=新的ProgressDelegate(ProgressCallback);
//做些工作
int pos=0;
做{
pos++;
//对控件进行线程安全调用,并对原始线程调用回调
//原始线程:创建窗体和控件的线程
progressBar1.Invoke(mydelegate,pos);
}而(pos<100);
}

我在猜测您的其他一些代码是什么样子,但您可能会移动此代码

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

对于
si_datareceived
方法,它将作为
BeginInvoke
调用的一部分执行,该调用的目标将在主(UI)线程上执行。

非常感谢,这似乎是我需要的。您已经在使用BeginInvoke了,我不明白问题的重点。Sleep()调用非常难看,实际上并不可靠。只是缓冲你得到的字符串片段。我想,我在几年前做了这个代码,我只是在更新它,但我同意,我有一个问题,com端口是虚拟化的,如果我删除线程。sleep它似乎出于某种原因试图回到com1,知道为什么吗?