【问题标题】:Thread safety issue: Cross-thread operation not valid线程安全问题:跨线程操作无效
【发布时间】:2012-01-10 11:12:52
【问题描述】:

我正在尝试在设备上收听,当收到一条消息时,首先在 datagridview 上显示它,但从设备获取消息效果很好,但问题是当我想设置我得到的 DGV 内容时此异常 跨线程操作无效,我已阅读this 相关主题。
但它们都没有帮助,因为没有绑定 DGV。
这是我的代码: 1.首先我有一个绑定到DGV的消息类,

public class Msg_log
{
    public Msg_log()
    {
        this.Event = null;
        this.Operator = null;
    }
    public string Event { get; set; }
    public string Operator { get; set; }
}

这是我在 loadform 事件中创建另一个线程的方法:

newThread = new System.Threading.Thread(this.Event_Listener);
        newThread.Start();   

在 Event_Listener 函数中

                x.Add(message);
                MsgDGV.DataSource = null;
                MsgDGV.DataSource = x;
                MsgDGV.Refresh();

消息对象是这样的:

Msg_log message = new Msg_log();

消息的Event和Operator变量已正确设置,我将MSG.DataSource = null,因为我想在新消息发送后更新我的DGV(实际上这是我的想法,如果有的话更好的方法我会很感激)这就是我得到的例外:跨线程操作无效。在其他帖子中,我发现我应该使用 Invoke 方法,但我不知道如何调用 Msg_DGV.Invoke(??,???);我不知道我应该传递什么来获得正确的结果...
干杯,

【问题讨论】:

标签: c# datagridview thread-safety


【解决方案1】:

您确实希望执行与您链接到的帖子相同的操作,只需将您的控件更改为使用 DataGridView。 C# Thread issues

Msg_DGV.Invoke(new Action( () => Msg_DGV.DataSource = null ) );

来自here 的更完整的示例,它不使用操作。

// The declaration of the textbox.
private TextBox m_TextBox;

// Updates the textbox text.
private void UpdateText(string text)
{
  // Set the textbox text.
  m_TextBox.Text = text;
}

//Now, create a delegate that has the same signature as the method that was previously defined:
public delegate void UpdateTextCallback(string text);

//In your thread, you can call the Invoke method on m_TextBox, 
//passing the delegate to call, as well as the parameters.
m_TextBox.Invoke(new UpdateTextCallback(this.UpdateText), 
            new object[]{”Text generated on non-UI thread.”});

【讨论】:

  • 我是这样做的,这对我有帮助:) Action show_DGV = delegate() { MsgDGV.DataSource = null; MsgDGV.DataSource = x; MsgDGV.Refresh(); }; this.MsgDGV.Invoke(show_DGV);
【解决方案2】:

您可以只使用 BackgroundWorker。

var bw = new BackgroundWorker();
bw.DoWork += (s, e) => {
                         ...
                         x.Add(message);
                         ...
                         e.Result = x;
                       };
bw.RunWorkerCompleted += (s, e) => MsgDGV.DataSource = e.Result;
bw.RunWorkerAsync();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多