Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / October 2007

Tip: Looking for answers? Try searching our database.

cross - thread problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Alistair George - 11 Oct 2007 19:15 GMT
if (e.Clicks > 0 && e.Button == MouseButtons.Middle)
            {
                f1.NewThread = new Thread(new
ThreadStart(f1.ShowMainNodes));
                f1.NewThread.Start();
            }

        private void ShowMainNodes()
        {
            API.POINTAPI papi = new ALaunch.API.POINTAPI();
            API.GetCursorPos(ref papi);
            Point p = new Point(papi.x /*- this.Location.X*/ , papi.y
/*- this.Location.Y - 16*/);
            this.Activate();  // x-thread error here - why; I thought
this was done in a thread-safe manner?
        }

Thank you.
//System.InvalidOperationException was unhandled
  Message="Cross-thread operation not valid: Control 'Form1' accessed
from a thread other than the thread it was created on."
  Source="System.Windows.Forms"
  StackTrace:
       at System.Windows.Forms.Control.get_Handle()
       at System.Windows.Forms.Form.Activate()
       at ALaunch.Form1.ShowMainNodes() in C:\Documents and
Settings\Alistair George\My Documents\Visual Studio
2005\Projects\Launcher\Form1.cs:line 335
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
Nicholas Paldino [.NET/C# MVP] - 11 Oct 2007 19:26 GMT
Alistair,

   Well, doing it in a thread-safe manner is one thing, but in this case,
you are making one (possibly two) calls to the UI on a thred that is not the
UI thread.

   You need to make the call to Activate on the same thread that the
control was created on.  Also, and I am not sure, the call to GetCursorPos
might have to be made on the UI as well (although I can see why it might not
be required).

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

>             if (e.Clicks > 0 && e.Button == MouseButtons.Middle)
>             {
[quoted text clipped - 28 lines]
> executionContext, ContextCallback callback, Object state)
>        at System.Threading.ThreadHelper.ThreadStart()
Alistair George - 11 Oct 2007 19:46 GMT
> Alistair,
>
[quoted text clipped - 6 lines]
> might have to be made on the UI as well (although I can see why it might not
> be required).

Ok, unfortunately, thats not clear - there is the old thread already
running, which I cant call as it conflicts with current mouse events,
hence the reason for starting a new thread. I dont call the old thread
from the new thread do I?
Nicholas Paldino [.NET/C# MVP] - 11 Oct 2007 19:54 GMT
Alistair,

   Well, yes, you could, by calling the Invoke method on the control, and
passing in a delegate which will execute the code on the UI thread.

   The thing is, the code you have shown doesn't really do much, and
shouldn't intefere with the UI thread at all.  It's very short, and doesn't
do much.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

>> Alistair,
>>
[quoted text clipped - 11 lines]
> hence the reason for starting a new thread. I dont call the old thread
> from the new thread do I?
Alistair George - 11 Oct 2007 20:44 GMT
> Alistair,
>
[quoted text clipped - 4 lines]
> shouldn't intefere with the UI thread at all.  It's very short, and doesn't
> do much.

I notice that where the form F1 is instantiated, it also has Single
threaded  [STAThread] set; is that a likely problem?
        [STAThread]
        static void Main()
        {
            Application.Run(f1);
        }
Nicholas Paldino [.NET/C# MVP] - 11 Oct 2007 20:57 GMT
Alistair,

   Well, it is the cause, but it's supposed to be there.  It's a
fundamental windows programming tennant that you have to make calls to UI
components on the same thread that they were created.  You are looking to
activate your form, so that call has to be made on the main thread.

   If you remove that attribute, your program is going to stop working in a
number of other places really quick.

   Now, there is no reason you can't get the cursor position and expose
those details to the worker thread, and then call Invoke to call a delegate
that will call Activate on your form when done.

   Of course, I still don't see why you have to, as the code you have is
very small, and shouldn't take long to run at all.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

>> Alistair,
>>
[quoted text clipped - 12 lines]
>             Application.Run(f1);
>         }
Alistair George - 12 Oct 2007 03:26 GMT
> Alistair,

Invoke to call a delegate
> that will call Activate on your form when done.
>
>     Of course, I still don't see why you have to, as the code you have is
> very small, and shouldn't take long to run at all.

Cheers Nicholas. Your help appreciated. I am quite clueless when it
comes to this part of programming never having been there before. C# is
much more picky than Delphi used to be, but I can figure its for stability.
Am trying to get the middle mouse button to activate a form, as well as
hotkey combo (which is working well). Catching the middle mouse button,
but from there the problem area is.
An alternative could be to simulate a hotkey press to activate the form.
Ignacio Machin ( .NET/ C# MVP ) - 11 Oct 2007 19:31 GMT
Hi,

You cannot use a Control from a thread other than the UI thread.
In these cases you need to use Control.Invoke

You can use any control to be used as the "hook"

>             if (e.Clicks > 0 && e.Button == MouseButtons.Middle)
>             {
[quoted text clipped - 28 lines]
> executionContext, ContextCallback callback, Object state)
>        at System.Threading.ThreadHelper.ThreadStart()
Alistair George - 11 Oct 2007 19:42 GMT
Thanks; how about some short examples for clarity.
Ignacio Machin ( .NET/ C# MVP ) - 11 Oct 2007 19:52 GMT
Hi,

> Thanks; how about some short examples for clarity.

Google Control.Invoke you will get a ton of examples as this is a VERY
recurrent question
Alistair George - 11 Oct 2007 20:15 GMT
> Hi,
>
>> Thanks; how about some short examples for clarity.
>
> Google Control.Invoke you will get a ton of examples as this is a VERY
> recurrent question

Thanks. Should have thought of that - been up since 4am working on this
problem!

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.