|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Newbie question: Thread access of form componentsI'm just getting familiar with Visual Studio and C#. I want to start a
thread that monitors a serial port and sends what comes across to a text box on the main screen. So, I create a thread to do that at the push of a button. However, when something comes in on the serial port, the program bombs because it says that I am trying to access a component (namely, the textBox) that was created in another thread. I tried calling Monitor.Enter(textBox1) and Monitor.Exit(textBox1) before and after the textBox1.Text = ... call, but still get the same error. Can someone give me a tiny example of how to access a component on the main form from within a thread? Thanks, Don use Invoke() method on the Control.
Show quoteHide quote "Don Tucker" <Don Tuc***@discussions.microsoft.com> wrote in message news:4C6A26FB-8B1F-4F0E-B67C-07512FDAC062@microsoft.com... > I'm just getting familiar with Visual Studio and C#. I want to start a > thread that monitors a serial port and sends what comes across to a text box > on the main screen. So, I create a thread to do that at the push of a > button. However, when something comes in on the serial port, the program > bombs because it says that I am trying to access a component (namely, the > textBox) that was created in another thread. I tried calling > Monitor.Enter(textBox1) and Monitor.Exit(textBox1) before and after the > textBox1.Text = ... call, but still get the same error. Can someone give me > a tiny example of how to access a component on the main form from within a > thread? > > Thanks, > Don I'm sorry. The documentation seems a bit sparse on Invoke. Do you mean,
_Activator.Invoke(textBox1,...) ? I don't understand how to use this? Don Show quoteHide quote "Lebesgue" wrote: > use Invoke() method on the Control. > > "Don Tucker" <Don Tuc***@discussions.microsoft.com> wrote in message > news:4C6A26FB-8B1F-4F0E-B67C-07512FDAC062@microsoft.com... > > I'm just getting familiar with Visual Studio and C#. I want to start a > > thread that monitors a serial port and sends what comes across to a text > box > > on the main screen. So, I create a thread to do that at the push of a > > button. However, when something comes in on the serial port, the program > > bombs because it says that I am trying to access a component (namely, the > > textBox) that was created in another thread. I tried calling > > Monitor.Enter(textBox1) and Monitor.Exit(textBox1) before and after the > > textBox1.Text = ... call, but still get the same error. Can someone give > me > > a tiny example of how to access a component on the main form from within a > > thread? > > > > Thanks, > > Don > > > Don, the Invoke() method that you're looking for is the Invoke method of the
TextBox itself inherited from the Control class. Basically visual controls should only be modified and methods called on the thread on which they were created. Since most developers create new forms on the main application thread (I believe that this is also a recomendation by MS) the Invoke method allows you to queue up control updates on the main thread from worker threads. It's very useful. Check out http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx Note the "Threads and Controls" section. Hope this helps Cordell Lawrence Teleios Systems Show quoteHide quote "Don Tucker" <DonTuc***@discussions.microsoft.com> wrote in message news:9E5C745F-35CE-44EB-AC1A-FA2C5BF9FA4A@microsoft.com... > I'm sorry. The documentation seems a bit sparse on Invoke. Do you mean, > _Activator.Invoke(textBox1,...) ? I don't understand how to use this? > > Don > > "Lebesgue" wrote: > > > use Invoke() method on the Control. > > > > "Don Tucker" <Don Tuc***@discussions.microsoft.com> wrote in message > > news:4C6A26FB-8B1F-4F0E-B67C-07512FDAC062@microsoft.com... > > > I'm just getting familiar with Visual Studio and C#. I want to start a > > > thread that monitors a serial port and sends what comes across to a text > > box > > > on the main screen. So, I create a thread to do that at the push of a > > > button. However, when something comes in on the serial port, the program > > > bombs because it says that I am trying to access a component (namely, the > > > textBox) that was created in another thread. I tried calling > > > Monitor.Enter(textBox1) and Monitor.Exit(textBox1) before and after the > > > textBox1.Text = ... call, but still get the same error. Can someone give > > me > > > a tiny example of how to access a component on the main form from within a > > > thread? > > > > > > Thanks, > > > Don > > > > > > OK. that helps a lot. I was able to get a version of the code from Figure 3
from the linked article to work (in my case, the textBox prints "hi" every time something comes over the serial port). However, in order to display the content of the serial port to the textBox, I need to get the snippet from Figure 4 working. There is an editor's note in the article that I don't really understand, also the creation of MyProgressEvents and MyProgressEventsHandler is confusion to me. Is there a simple mod to the Figure 3 code to allow passing arguments into the UpdateUI method? Don Show quoteHide quote "Cordell Lawrence" wrote: > Don, the Invoke() method that you're looking for is the Invoke method of the > TextBox itself inherited from the Control class. Basically visual controls > should only be modified and methods called on the thread on which they were > created. Since most developers create new forms on the main application > thread (I believe that this is also a recomendation by MS) the Invoke method > allows you to queue up control updates on the main thread from worker > threads. It's very useful. > > Check out > http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx > Note the "Threads and Controls" section. > > Hope this helps > Cordell Lawrence > Teleios Systems > > > "Don Tucker" <DonTuc***@discussions.microsoft.com> wrote in message > news:9E5C745F-35CE-44EB-AC1A-FA2C5BF9FA4A@microsoft.com... > > I'm sorry. The documentation seems a bit sparse on Invoke. Do you mean, > > _Activator.Invoke(textBox1,...) ? I don't understand how to use this? > > > > Don > > > > "Lebesgue" wrote: > > > > > use Invoke() method on the Control. > > > > > > "Don Tucker" <Don Tuc***@discussions.microsoft.com> wrote in message > > > news:4C6A26FB-8B1F-4F0E-B67C-07512FDAC062@microsoft.com... > > > > I'm just getting familiar with Visual Studio and C#. I want to start > a > > > > thread that monitors a serial port and sends what comes across to a > text > > > box > > > > on the main screen. So, I create a thread to do that at the push of a > > > > button. However, when something comes in on the serial port, the > program > > > > bombs because it says that I am trying to access a component (namely, > the > > > > textBox) that was created in another thread. I tried calling > > > > Monitor.Enter(textBox1) and Monitor.Exit(textBox1) before and after > the > > > > textBox1.Text = ... call, but still get the same error. Can someone > give > > > me > > > > a tiny example of how to access a component on the main form from > within a > > > > thread? > > > > > > > > Thanks, > > > > Don > > > > > > > > > > > > I've never had that problem.
Is the method the thread runs in the same class as the control? That's how I do it. "PIEBALD" <PIEB***@discussions.microsoft.com> wrote in message And that's exactly how you should NOT do it.news:95712E98-B89B-4129-968F-7DF80AD5857B@microsoft.com... > I've never had that problem. > Is the method the thread runs in the same class as the control? > That's how I do it. > > A Windows application that has separate threads that update the UI, it's only the thread that created the UI element (Control) who is allowed to directly touch that Control, other threads must marshal the call so the methods executes on the UI thread. The frameworks supports this marshaling through the Control.Invoke or Control.BeginInvoke members. Willy. So I guess I'll have my other thread create the control too.
Oh, wait, what if the control spawns a thread to update itself? PIEBALD <PIEB***@discussions.microsoft.com> wrote:
> So I guess I'll have my other thread create the control too. It's still not the UI thread for that control. It's only the thread > > Oh, wait, what if the control spawns a thread to update itself? which creates the control which is allowed to access it. See http://www.pobox.com/~skeet/csharp/threads/winforms.shtml -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too But what exactly is the problem? If it's just that you should only have one
thread doing it, then why does it matter which thread? Also, what if I have a thread that creates controls for other threads and then terminates? How does a control know what thread created it? PIEBALD <PIEB***@discussions.microsoft.com> wrote:
> But what exactly is the problem? If it's just that you should only have one Because that's the way Windows works. This isn't a .NET issue, it's a > thread doing it, then why does it matter which thread? Windows issue. (It's also the way some other windowing systems work.) > Also, what if I have a thread that creates controls for other threads and I don't know the details of exactly how it all works, but I don't think > then terminates? How does a control know what thread created it? it's worth worrying too much about it - just treat it as a given rule to obey. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too "PIEBALD" <PIEB***@discussions.microsoft.com> wrote in message It's a rule in windows that says NOT to use a "window" handle (actualy a GDI news:FC2CF30B-3983-444D-97A2-F7F13FCB7F12@microsoft.com... > But what exactly is the problem? If it's just that you should only have > one > thread doing it, then why does it matter which thread? > handle) associated with a window control from another thread than the owning thread, simply stated Window handles have thread affinity. Most of the time and for most actions on controls it works, but there are times it breaks in a bad way. V2.0 of the framework includes a debug probe to guard against this cross-thread control access and will throw an exception in debug mode. > Also, what if I have a thread that creates controls for other threads and And how is one thread going to ask another thread to create a control, by > then terminates? How does a control know what thread created it? marshaling the call, right? so the creating thread becomes the owner of the control, but look, a control can only be created if there is a parent window (say the main application window) owned by the same thread, so this thread is responsible for disposing all controls in the chain starting from the top window when terminating. A control doesn't know which thread is the owner, the OS knows it and an application can ask if the current thread owns the control handle by checking the Control.InvokeRequired property. Willy. Ah! OK, I was finally able to get it working with the sample provided from
the link below. Thanks for much everyone! Don Show quoteHide quote "Jon Skeet [C# MVP]" wrote: > PIEBALD <PIEB***@discussions.microsoft.com> wrote: > > So I guess I'll have my other thread create the control too. > > > > Oh, wait, what if the control spawns a thread to update itself? > > It's still not the UI thread for that control. It's only the thread > which creates the control which is allowed to access it. > > See http://www.pobox.com/~skeet/csharp/threads/winforms.shtml > > -- > Jon Skeet - <sk***@pobox.com> > http://www.pobox.com/~skeet > If replying to the group, please do not mail me too >
Other interesting topics
"Object does not match target type." using dynamic compiling & inv
InitializeComponent changes TabPage order without warning Nontrivial structure? Covariance in delegates doesn't work with ValueType's? events and eventargs Retrieve new row identity in C# Draw Fingerprint Readers C# Eletitlement app - Can this be done Variable references |
|||||||||||||||||||||||