Thread question

Hi, I have a winform application that fire a thread that verifies a
database, if the database has some new entry, the thread needs to
communicate the main thread..

How can I do this via message via event via fire balls =P

Thanx!



Answer this question

Thread question

  • Arnaut

    hehehe

    but using events I would not need to put main thread in the wait state (freeze)

    I want to know how can I create message handlers, like Delphi have the message reserved word.

    C# have some way like this simple

    or something like synchronyze method, that runs the procedure on the main thread.

    thanx


  • Greg M.

    Are you using .NET 2.0 If so, use the new BackgroundWorker class. If not, Google "BackgroundWorker" for a .NET 1.1 implementation.
  • Mohan Giri

    Hi, thanx for the help =)

    I choose the way of the messages, just passing the handle to the sendmessage...

    thanx a lot =D

  • Tramp

    I may seem quite stupid on this one, but how about just using the Remoting structure to hold that messaging using a simple local tcp stack Both threads would run independently and you just need to create your Remoting events...

    Moreover, this would provide some basic scalability...

    Just a simple suggestion to see if it would work...

    Amadrias

  • Gomezd01

    You're correct that you need to marshal this back to the UI thread.

    Control has a member called Invoke to handle this.  Do something like this:




    public class Form1 : Form {
       private void SomeButtonClick(object s, EventArgs e) {
          new Thread(ThreadProc).Start();
       }

       private void ThreadProc() {
          DoABunchOfStuff();

        
          this.Invoke(new EventHandler(OnStuffDone), new object[]{this, EventArgs.Empty});      

       }

       private void OnStuffDone(object sender, EventArgs e) {
          this.Text = "Done!";
       }

    }

     


    Use BeginInvoke if you don't need to wait for the marshalling call to complete.



  • Roberto H.

    Not to many people would want to use your applications if you shot a fireball at them every time the database had a new entry.  I think raising an event would be a better choice.


  • CA_VB2005er

    Hi, I tried to use what yout told me...

    but the wnd proc doesn't enter in my case statement  = (

    the break point into wndproc it's ok, but my message is not correctly sent..

    the code is attached

    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public extern static IntPtr SendMessage(IntPtr hwnd, uint msg, uint wParam, uint lParam);

    ...

    SendMessage(IntPtr.Zero, 123123, 0, 0);

    ...

    protected override void WndProc(ref Message AMessage)
    {
      switch(AMessage.Msg)
      { 
        case UnitConstants.VT_CASERECIEVED:
        {
          MessageBox.Show("aaaa");
        }
    break;
      } 

      base.WndProc(ref AMessage);
    }


  • Michael Fanning - MS

    You have to pass the handle for the form in sendmessage for wndproc to recieve it 



    namespace WindowsApplication1
    {
        public partial class Form1 : Form
        {

            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public extern static IntPtr SendMessage(IntPtr hwnd, uint msg, uint wParam, uint lParam);


            public Form1()
            {
                InitializeComponent();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                SendMessage(this.Handle, 123, 0, 0);
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == 123)
                {
                    MessageBox.Show("Test");
                }
                base.WndProc(ref m);
            }
        }
    }

     



  • imj

    It's not about getting the info from one place to another (you could just use a member or a method for that), it's about thread affinity.  Using remoting would be overkill here and would still call you back on the wrong thread leaving you in no better shape.

    The Windows Forms components can only be called from the thread they were created on (actually the thread they created their handle on, but in 99.999% of the cases that's the same), so you need to marshal from one thread to another to do the call correctly.

    BackgroundWorker makes this easy in VS2005 by simply using the DoWork event to to do your background work and do the update of the UI in the WorkCompleted event.

  • Robert101

    The Control.Invoke methiod is much preferred to the SendMessage method.



  • IT Professional

    You could use the sendmessage api to send a message that you could recieve by overriding the forms wndproc.  An event like databaseHasChanges should not lock the main thread unless you are doing something time consuming in the event handler.  It is kind of hard to be specific without knowing how you are detecting changes in the database and what type of database engine you are using.

    You could use control.invoke to update the ui from a background thread.



  • iknowso

    You are right control.invoke is much better

  • Kaulu84

    To see an example of the BackgroundWorker in action check out the Application at the bottom of the page - http://www.windowsforms.net/Default.aspx tabindex=9&tabid=3

    App Summary -
    This application uses the BackgroundWorker component and the DataGridView control (both new to Visual Studio 2005) to asynchronous load data into the DataGridView. The sample performs a “find in files” type of search on a background thread using the BackgroundWorker component. As file matches are found, the file info is reported back to the DataGridView to display the data using the ReportProgress method.

  • Thread question