线程安全问题:跨线程操作无效

时间:2012-01-10 11:12:52

标签: c# datagridview thread-safety

我正在尝试在设备上收听,并且当从第一个数据网格中看到它时显示它的消息但是从设备获取消息的工作完美,但问题是当我想设置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(??,???);我不知道应该通过什么来获得正确的结果...
欢呼声,

2 个答案:

答案 0 :(得分: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.”});

答案 1 :(得分:1)

您可以使用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();