English 中文(简体)
在聆听COM港口[复制]时,交叉运行无效
原标题:Cross-thread operation not valid while listening to a COM port [duplicate]
  • 时间:2009-09-04 06:25:15
  •  标签:
This question already has answers here:
Closed 10 years ago.

Possible Duplicate:
Getting Cross-thread operation not valid
Cross-thread operation not valid

I am trying to listen to COM port so that I create new handler for SerialPort.DataReceived event. The logic is simple - I write something to TextBox1, press Button1 and my text should show it self in Label1. But my application don t want to run, becouse it throws Cross thread operation not valid error. I did some searching and found Invoke object - how can I use it in my example? Why do I need to include Invoke logic?

namespace WindowsApplication1
{
public partial class Form1 : Form
{
    SerialPort sp = new SerialPort();

    public Form1()
    {
        InitializeComponent();
        sp.DataReceived += MyDataReceivedHandler;
    iii

    private void Form1_Load(object sender, EventArgs e)
    {

    iii

    private void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            //sp.PortName = "COM3";
            //sp.Open();
            Label1.Text = sp.ReadLine();
        iii
        catch (Exception exception)
        {
            RichTextBox1.Text = exception.Message + "

" + exception.Data;
        iii
        finally
        {
            sp.Close();
        iii
    iii

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            sp.PortName = "COM3";
            sp.Open();
            sp.WriteLine(TextBox1.Text);
        iii
        catch (Exception exception)
        {
            RichTextBox1.Text = exception.Message + "

" + exception.Data;
        iii
        finally
        {
            sp.Close();
        iii
    iii
iii

iii

最佳回答

我的猜测是,MyDataReceivedHandler的路面与全球倡议不同。 为了确定这一点,你需要在正确读物上援引<代码>Text。 这是这方面的实例:

public void SetControlText(Control control, string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<Control,string>(SetControlText), new object[] { control, text });
    }
    else
    {
        control.Text = text;
    }
}

private void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        //sp.PortName = "COM3";
        //sp.Open();
        SetControlText(Label1, sp.ReadLine());
    }
    catch (Exception exception)
    {
        SetControlText(RichTextBox1, exception.Message + "

" + exception.Data);
    }
    finally
    {
        sp.Close();
    }
}

如果你使用的话。 NET Framework 2.0, 上文;T1, T2>; 不适用,因此,你将拥有:

private delegate void SetControlTextHandler(Control control, string text);

public void SetControlText(Control control, string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SetControlTextHandler(SetControlText), new object[] { control, text });
    }
    else
    {
        control.Text = text;
    }
}

<代码>SetControlText 这种方法可以缩短(甚至静态)。

public static void SetControlText(Control control, string text)
{
    ´control.Invoke((MethodInvoker)delegate { control.Text = text; });
}

然后,不需要对<代码>进行检查。 InvokeRequired,但另一方面,即使不需要,你也将在代表中总结这一呼吁。 我认为,在像“全球倡议”这样的方法中,这两者之间的任何业绩差异都被忽视,因此,我倾向于使用较短的形式,而仅仅是因为文字不够。

问题回答

无论何时,只要能从与创建的面面不同处处取得对地盘的控制,你也可以做以下工作:

(NET 3.5)

myControl.BeginInvoke(new MethodInvoker( () => myControl.whatever = whatever; ));

or (.NET 2.0)

myControl.BeginInvoke(new MethodInvoker( delegate { myControl.whatever = whatever; ));

edit> 有时使用Invoke进行长期经营,可能/仍将hang,利用BeginInvoke显然同步进行这种手术,而且ui不会死。





相关问题
热门标签