0

i am using the following function plot() to plot data on google maps.now when i am calling the same function from another button click event it is not getting executed rather going into else() statement.my plot function is as follows:

 public void plot(double temp_lat, double temp_long, string temp_date, string temp_time, string temp_bty_value)
 {
        if (this.InvokeRequired)
        {
            // do something
        } 
        else { this.Close(); }
 }

i am calling this function from button click event as follows:

private void button6_Click_1(object sender, EventArgs e) /// refresh button
{
      this.Invoke((MethodInvoker)(() => 
                   { 
                        plot(28.5231445, 77.40388525, "17/06/20", "17:00:50", "82"); 
                   }));
}

when is the reason for this? i am new to invoking methods.please help Edit:https://stackoverflow.com/a/43797637/6412780 The reason why i am using invocation because i was plotting 5 markers simultaneously on gmap from different threads.so for synchronization i am using invocation method.BUT now i want to update my data. i made a refresh button which contains new lat /long (passing manually here) to plot on the map.being on the same UI i called the plot() function directly ,but even then i wasn't able to execute the if statement. that is what i am doing .

pranjal khanduri
  • 351
  • 1
  • 3
  • 16
  • 6
    There is no reason to invoke here. – Patrick Hofman Jul 06 '17 at 09:28
  • 3
    You're already calling `Invoke` in `button6_Click_1`, so `plot` is being called in the UI thread, therefore `InvokeRequired` will return false. It's not clear what's surprising about this. – Jon Skeet Jul 06 '17 at 09:29
  • here InvokeRequired doesn't mean your `plot` method has to be called or not but rather if dispatching the call to the UI thread is necessary – Ventsyslav Raikov Jul 06 '17 at 09:35
  • What is the *actual* problem you want to solve? There's no reason to use `Invoke()` when you are *already* on the UI thread. Did you encounter a different problem and tried to "simplify" the code? Did you try to run something in the background and update the UI from the results in the wrong way? – Panagiotis Kanavos Jul 06 '17 at 09:39
  • The problems you're having with Invoke seem to stem from bad coding choices in the overall design. There should not be an "if" in a function called "plot". Why would anyone expect the form to close when they call "plot"?? That "if" should be done somewhere more sensible (can't tell you where from your snippet) & plot should just be left to "plot" – Ashley Pillay Jul 06 '17 at 10:27
  • Concurrent programming is difficult. Even for programmers with years of experience, there are so many nuances, and UI complicates things further. If you don't have that level of experience with the language, and it's obvious you do not, you should do this as a straight forward synchronous flow. It might be a bit slower, but you will be able to understand what's going on & can maintain it yourself. – Ashley Pillay Jul 06 '17 at 10:32

2 Answers2

0

In WinForms all1 UI operations – anything accessing any member of any control instance – need to be performed on the single thread executing UI operations.

Invoke can be used by a non-UI thread to cause the UI thread to execute code (with BeginInvoke this can be concurrently).

But an event handler for a control will always be running on the UI thread when triggered by the UI. So no need to switch threads. To run code on a different thread (eg. it would block the UI thread) there are various options, these days using async/await, to let the runtime work it out, is preferred.

In the question's code the event handler is already using Invoke which is pointless: it is already on the UI thread.

1 Simplifying here, the actual rules have subtleties for advanced use cases.

Richard
  • 106,783
  • 21
  • 203
  • 265
0

Invocation is required if you try to access elements, that are exclusive to one Threadfrom another Thread. It is very common when accessing GUI elements from a background thread. Here is an example:

    Thread t = new Thread(() => plot(28.5231445, 77.40388525, "17/06/20", "17:00:50", "82"));

    public void plot(double temp_lat, double temp_long, string temp_date, string temp_time, string temp_bty_value)
    {
        if (this.InvokeRequired)
        {
           this.Invoke((MethodInvoker)(() => 
               { 
                    this.Close();  
               }));
        } 
        else { 
           this.Close(); 
        }
     }

thisseems to be a Form. If you call the Close method from another Thread you will most likely get an Exception (There are ways to prevent this, but thats not considered good style). You need to invoke that method (let the Form decide, when it is ready to execute the command)

Romano Zumbé
  • 7,893
  • 4
  • 33
  • 55