Help needed for 'cross-thread operation error' in C#

后端 未结 6 2015
野的像风
野的像风 2021-01-16 03:34

In the following code MessageReceived is on a different thread to label1 and when trying to access it I will get this error:

相关标签:
6条回答
  • 2021-01-16 04:15

    In your Agent class, when you raise the MessageReceived event, you'll have to check whether the Target of the event-handler implements ISynchronizeInvoke. If it does, and if the InvokeRequired property returns true, you'll have to invoke the eventhandler.

    If you're not using WinForms, but WPF, you cannot rely anymore on ISynchronizeInvoke since the WPF controls do not implement that interface. Instead, you'll have to work with AsyncOperation and AsyncOperatoinManager.

    0 讨论(0)
  • 2021-01-16 04:17

    Hopefully this will be closed as an exact duplicate, but if not:

    Don't touch the GUI from a non-GUI thread. Use BackgroundWorker and report progress appropriately, or read the WinForms page of my threading article for more direct control (Control.Invoke/BeginInvoke).

    0 讨论(0)
  • 2021-01-16 04:23

    Delegate updating the label to the thread that created the label instead of trying to update it directly.

    0 讨论(0)
  • 2021-01-16 04:27

    You need to use Control.Invoke (or Control.BeginInvoke). First, create a new Windows Forms application and add a label and a button. Double click on the button in Visual Studio to edit it's Click event and add the following code:

        private void button1_Click(object sender, EventArgs e)
        {
            new System.Threading.Thread(new System.Threading.ThreadStart(Run)).Start();
        }
    
        void Run()
        {
            label1.Invoke(new Action(delegate()
            {
                label1.Text = System.Threading.Thread.CurrentThread.Name + " " + System.DateTime.Now.ToString();
            }));
        }
    
    0 讨论(0)
  • 2021-01-16 04:28

    Make always sure you update your GUI on the main thread (GUI thread).

    foo.MessageReceived += new Agent.MessageReceivedHandler(foo_MessageReceived);

    public delegate void MyDelegate(Message msg);
    void foo_MessageReceived(Message message)
    { 
       if (InvokeRequired)
       {
          BeginInvoke(new MyDelegate(foo_MessageReceived),new object[]{message});
       }
       else
       {
          label1.Text = message.Body;
       }
    }
    
    0 讨论(0)
  • 2021-01-16 04:32

    This is totally not helpful. I wish I could vote myself down.

    I may be out of date, but from what I remember you aren't allowed to alter anything in the GUI from anything but the main thread.

    0 讨论(0)
提交回复
热议问题