0

I am trying to listen on a device and when got a message from that showing it on a datagridview the first but getting the message from the device works perfectly, but the problem is that when I want to set the DGV content I got this exception Cross-thread operation not valid, and I have read this related topic.
but none of them was helpful since there weren't on a binding DGV.
here is my code: 1. first I have a message class which is binded to the DGV,

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

and here is how I create another thread in the loadform event:

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

and in the Event_Listener function

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

the message object is like this:

Msg_log message = new Msg_log();

and its Event and Operator variables of message have been set correctly, and I put the MSG.DataSource = null, since I want to update my DGV after the new message is comming (Actually this was my idea and if there is any better way for that I would appreciate that) and that's the line I got the exeption:Cross-thread operation not valid. In the other posts I found out that I should use Invoke method but I don't know how to call Msg_DGV.Invoke(??,???); I don't know what should I pass to that to get the right result...
Cheers,

Community
  • 1
  • 1
Ehsan
  • 4,334
  • 7
  • 39
  • 59
  • Create a method to handle set the DGV DataSource and Refresh to the DGV and call MsgDGV.Invoke(myDelegate,vnew Object[] {x}); http://msdn.microsoft.com/en-us/library/a1hetckb – Lloyd Jan 10 '12 at 11:20

2 Answers2

1

You do want to do the same as that post you linked to, just change your control to use a DataGridView. C# Thread issues

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

A more full blown example from here that doesn't use Actions.

// 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.”});
Community
  • 1
  • 1
Ian
  • 33,605
  • 26
  • 118
  • 198
  • I made it sth like this and this helped I think:) Action show_DGV = delegate() { MsgDGV.DataSource = null; MsgDGV.DataSource = x; MsgDGV.Refresh(); }; this.MsgDGV.Invoke(show_DGV); – Ehsan Jan 10 '12 at 11:24
1

You could just use 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();
clearpath
  • 916
  • 8
  • 24