Author | Message | Time |
---|---|---|
TehUser | I have an asynchronous socket class that I instantiate in my program. It has several delegates to handle the various events on the socket. I add the handlers in my program and attempt to modify GUI elements on the various events. An error pops up saying that a control may not be modified from another thread (.NET 1 didn't like you doing this, but wouldn't throw an exception). In searchin the net, there is a lot of talk about using the Invoke method to return control to the GUI thread before updating. Rather than adding an Invoke for every single piece of GUI I want to update, what is the correct way to notify a GUI thread about an event from an instantiated class? [MyndFyre edit: I changed the topic title; first I was going to just remove the [.NET 2.0] part, but really I also wanted to make the topic title more clear about what you're dealing with] | February 24, 2005, 3:34 PM |
kamakazie | Using Invoke is the correct and only way. Might want to take a look at [url]http://blogs.msdn.com/ericgu/archive/2003/08/23/52502.aspx[/url]. | February 24, 2005, 6:25 PM |
Myndfyr | You can also use the BeginInvoke method on the Control class. This allows the code performing the action to continue to execute, as the call to BeginInvoke returns immediately, as opposed to the Invoke call, which waits until the GUI thread returns. For example, in my new bot project, in my common controls library, I have a class that processes chat text and then assigns RTF, control words and all, to the RichTextBox.Rtf property of a rich text box instance. Here is the code that does it: [code] #region set rtf code private delegate void TextCallback(string text); /// <summary> /// Sets the rich-text-format text of the chat text box control. /// </summary> /// <param name="rtf">The string of RTF, including all control words.</param> public virtual void SetRtf(string rtf) { if (this.Handle == IntPtr.Zero) { this.CreateHandle(); } this.BeginInvoke(new TextCallback(SetTextCallback), new object[] { rtf }); } private void SetTextCallback(string rtf) { m_mutRtf.WaitOne(); if (m_autoScroll) { this.rtbChat.Rtf = rtf; ScrollIntoView(); } m_mutRtf.ReleaseMutex(); } #endregion [/code] (full code can be found here). The SetRtf(string) function, which is public, simply sets up the method to be called. The delegate passed into BeginInvoke is a function pointer to the SetTextCallback(string) function, which ensures that it is thread safe (the m_mutRtf is a Mutex object on the class) and then assigns the Rtf property of the RichTextBox. Hth! | February 25, 2005, 12:37 AM |