2017-07-06 86 views
0

我正在使用以下函数plot()来绘制谷歌地图上的数据。现在,当我从另一个按钮点击事件调用相同的功能时,它不会执行,而是进入else() statement.my plot函数是如下:c#:调用方法

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(); } 
} 

我打电话从按钮单击事件这个功能如下:

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"); 
        })); 
} 

时,是什么原因呢?我是新的援引methods.please帮助 编辑:https://stackoverflow.com/a/43797637/6412780我之所以使用调用,因为我在不同线程的gmap上同时绘制5个标记。我为synchronization我正在使用调用method.BUT现在我想更新我的数据。我做了一个刷新按钮,其中包含新的经纬度(手动通过此处)在地图上绘制。在同一UI上,我直接调用了plot()函数,但即使如此,我仍然无法执行if statement。这就是我正在做的事情。

+6

没有理由在这里调用。 –

+3

您已在'button6_Click_1'中调用'Invoke',所以'plot'正在UI线程中调用,因此'InvokeRequired'将返回false。目前尚不清楚有什么令人惊讶的。 –

+0

这里InvokeRequired并不意味着你的'plot'方法必须被调用或不需要,而是需要调用UI线程的调用 – Bond

回答

0

在WinForms中全部 UI操作 - 任何访问任何控件实例的任何成员的任何操作 - 都需要在执行UI操作的单个线程上执行。

Invoke可由非UI线程使用以使UI线程执行代码(可以同时使用BeginInvoke)。

但是,由UI触发时,控件的事件处理程序将始终在UI线程上运行。所以不需要切换线程。为了在不同的线程上运行代码(例如,它会阻塞UI线程),有很多选项,这些日子使用async/await来让运行时间运行它是首选。

在问题的代码中,事件处理程序已经在使用Invoke这是毫无意义的:它已经在UI线程上。

这里简化一下,实际的规则对于高级用例来说是微妙的。

0

如果您尝试访问另一个ThreadThread专用的元素,则需要调用。从后台线程访问GUI元素时非常普遍。这里有一个例子:

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(); 
     } 
    } 

this似乎是一个Form。如果你从另一个Thread调用Close方法,你很可能会得到一个Exception(有许多方法可以防止这种情况发生,但那不是很好的风格)。你需要调用该方法(让Form决定,当它准备好执行命令时)