【问题标题】:c#: Invoking Methodsc#: 调用方法
【发布时间】:2017-07-06 18:06:45
【问题描述】:

我正在使用以下函数 plot() 在谷歌地图上绘制数据。现在,当我从另一个按钮单击事件调用相同的函数时,它没有被执行,而是进入 else() 语句。我的绘图函数是如下:

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

这是什么时候的原因?我是调用方法的新手。请帮助 编辑:https://stackoverflow.com/a/43797637/6412780 我使用调用的原因是因为我从不同的线程同时在 gmap 上绘制 5 个标记。所以对于synchronization,我正在使用调用方法。但是现在我想更新我的数据。我制作了一个刷新按钮,其中包含新的纬度/经度(在此处手动传递)以在地图上绘制。在我直接调用 plot() 函数的同一 UI 上,但即便如此我也无法执行 if statement .这就是我正在做的。

【问题讨论】:

  • 这里没有理由调用。
  • 您已经在button6_Click_1 中调用了Invoke,因此在UI 线程中调用了plot,因此InvokeRequired 将返回false。目前尚不清楚这有什么令人惊讶的。
  • 这里 InvokeRequired 并不意味着您的 plot 方法是否必须被调用,而是是否需要将调用调度到 UI 线程
  • 您想解决的实际问题是什么?当您已经在 UI 线程上时,没有理由使用 Invoke()。您是否遇到了不同的问题并试图“简化”代码?您是否尝试在后台运行某些东西并以错误的方式从结果中更新 UI?
  • 您在使用 Invoke 时遇到的问题似乎源于整体设计中的错误编码选择。在名为“plot”的函数中不应有“if”。为什么有人会在他们调用“情节”时期望表单关闭?那个“如果”应该在更明智的地方完成(不能告诉你从你的 sn-p 哪里)&情节应该留给“情节”

标签: c# winforms invoke begininvoke


【解决方案1】:

在 WinForms 中,所有1 UI 操作——访问任何控件实例的任何成员的任何操作——都需要在执行 UI 操作的单个线程上执行。

Invoke 可以被非 UI 线程使用,以使 UI 线程执行代码(BeginInvoke 可以是并发的)。

但是当被 UI 触发时,控件的事件处理程序将始终在 UI 线程上运行。所以不需要切换线程。要在不同的线程上运行代码(例如,它会阻塞 UI 线程),有多种选择,现在使用 async/await 让运行时解决它是首选。

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

1 在这里简化一下,实际的规则对高级用例有微妙之处。

【讨论】:

    【解决方案2】:

    如果您尝试访问一个 Thread 和另一个 Thread 独有的元素,则需要调用。从后台线程访问 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 决定,何时准备好执行命令)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多