locked
calling Invoke RRS feed

  • Question

  • I would appreciate some help with this. My apologies in advance if the subject is trivial. I have a GPS object that runs on it's own thread. When new GPS information arrives, I call Invoke to display the new information on my Form. It does not seem to work properly. It usually works but sometimes the form locks up. I looked at the manual pages and they say the delegate passed to invoke must be an instance of EventHandler in the >NET compact framework, which is what I am using (I am writing a smart phone application). So my question is How would I do this exactly. The delegate I am calling is simply a Method of my Control class that updates some text . I am attaching the relevant parts of the code.

    Thanks,
    Reza
     partial class RecorderForm : Form
     {
            private Gps gps = new Gps();
    
            public RecorderForm()
            {
                InitializeComponent();
                gps.Open();
                gps.LocationChanged += ShowGPSInfo;
            }
    
            private void ShowGPSInfo(object sender, LocationChangedEventArgs args)
            {
                string s = ...;
                Invoke(new XXX(SetLabelGPSInfo), s);
             }
    
            private delegate void XXX(string s);
    
            private void SetLabelGPSInfo(string s)
            {
                labelGPSInfo.Text = s;
            }
    }
    Saturday, November 28, 2009 5:33 PM

Answers

  • Thanks for all the Help Tamer. It turns out I had to call BeginInvoke in my code instead of Invoke from the GPS thread to dump the GPS data to the screen. Otherwise calling GPS.Close() could result in a deadlock. It happend to be the topic of discussion on another thread some time ago but funny enough that thread did not come up when I was posing the question originally.

    Anyway, my problem is solved. If anyone lookas at this thread in the future, do not call Invoke from the GPS thread. Call BeginInvoke instead.

    Thanks again.
    • Marked as answer by Reza65 Tuesday, December 1, 2009 12:04 PM
    Tuesday, December 1, 2009 6:31 AM

All replies

  • Hi,

    put the following code into your form and just call SetLabelGPSInfo(s) from your thread.

                public delegate void SetLabelGPSInfoDelegate(string value);
                private void SetLabelGPSInfo(string value)
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new SetLabelGPSInfoDelegate(SetLabelGPSInfo), value);
                    }
                    else
                    {
                        labelGPSInfo.Text=value;
                    }
    
    
                }
    Saturday, November 28, 2009 5:41 PM
  • Thanks. I tried it and I still have the same problem. The difference between what I have and what you suggested is that I always call invoke. Your code, on the other hand, tests if invoke is required and calls the method directly if it is not. Let me tell you what my exact problem is. It might be helpful. I have an exit button. If I click the button after the text is displayed (i.e., SetLabelGPSInfo executes), it exits the application. However, if I click on the exit button immediately after the application starts and before SetLabelGPS executes for the first time, the form freezes up. The problem is most likely with Invoke since when I remove it, the form never freezes up.

    Reza
    Saturday, November 28, 2009 6:49 PM
  • Hi,

    I think the problem is from the component you are using. It somehow keep the thread open I guess.

    In normal circumstances it should work fine.

    try calling a method like gps.close() just before you exit the application, or ask the developer of the component.
    Sunday, November 29, 2009 6:59 AM
  • I think you might be correct. I have been looking at this for two days now and I am beginning to think the problem may not be in my code.

    I do call gps.Close() before I exit. This is the .Net API microsoft has written for using the GPS driver. I have the latest version as far as I know but I still don't trust it. For example, therey provide an overloaded version of the GetPosition: GpsPosition GetPosition(TimeSpan s). It is supposed to return the latest position data as long as it is not older than specified by the parameter. I was calling the function in my code but it didn't seem to be working. I then looked at the source code and found out that they comapre the system clock to the time component in the GPS signal (which is UTC time) to decide if the signal is too old. Stange since the code was written some time ago.

    This is for my own education. I am new to GUI programming. I was assuming that the form will close cleanly when I call Close() or Application.Exit() whether or not it has an outstanding Invoke(). I was also assuming that when I call gps.Close() the designer of that component would terminate the GPS thread cleanly so that Invoke is not called on my Form after Close() returns. If all of this happens, as you said, I should be able to exit no matter what state the GPS thread is in and whether or not I have a function in my Form scheduled to run on the GUI thread (the request having been made by the GPS thread through Invoke). Am I correct in my assumptions?

    Thanks for the help.
    Sunday, November 29, 2009 12:33 PM
  • Hi,

    You are right about yourassumptions. But there is one point.

    If you start a thread and if it is not finished before you are closing application if you don't abort it your process will not be killed.

    Here is a sample.

            public Form5()
            {
                InitializeComponent();
    
    
    
            }
    
            Thread t = null;
            private void Form5_Load(object sender, EventArgs e)
            {
               t = new Thread(DoWork);
                t.Start();
            }
            public void DoWork()
            {
                Thread.Sleep(100000);
            }
    
            private void Form5_FormClosing(object sender, FormClosingEventArgs e)
            {
                //if you don't abort thread your process will be kept open
                if (t != null)
                {
                    if (t.IsAlive)
                    {
                        t.Abort();
                    }
                }
            }
    Sunday, November 29, 2009 12:48 PM
  • Right. But I have only two threads: the GUI thread and the thread started by the GPS object when I call GPS.Open(). So if GPS.Close(0 does its job, I should be able to exit the application since I call it before exiting.

    Unfortunately there is no clean way I can take care of this problem outside the GPS class. I took a look at it; it makes calls to MFC functions, so to fix it I would have to try and understand and then fix MFC code. When I first saw MFC many years ago, I said to myself I will never have anything to do with it! I am going to keep that promise.

    Thanks for the helpful comments though. I think I will post on the Windows mobile forum (if there is one) just in case someone has a fix for the GPS class.
    Monday, November 30, 2009 6:57 PM
  • Thanks for all the Help Tamer. It turns out I had to call BeginInvoke in my code instead of Invoke from the GPS thread to dump the GPS data to the screen. Otherwise calling GPS.Close() could result in a deadlock. It happend to be the topic of discussion on another thread some time ago but funny enough that thread did not come up when I was posing the question originally.

    Anyway, my problem is solved. If anyone lookas at this thread in the future, do not call Invoke from the GPS thread. Call BeginInvoke instead.

    Thanks again.
    • Marked as answer by Reza65 Tuesday, December 1, 2009 12:04 PM
    Tuesday, December 1, 2009 6:31 AM
  • Hi,

    Glad to see that you got it resolved, by the way, if you can mark those useful replies as answers, other community members who encounter similar issue will benefit a lot from this thread.

     

    Thanks,

    Eric


    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    Tuesday, December 1, 2009 9:27 AM