AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77033849
Accepted
sdbbs
sdbbs
Asked: 2023-09-04 03:22:39 +0800 CST2023-09-04 03:22:39 +0800 CST 2023-09-04 03:22:39 +0800 CST

可以从另一个组件启动并等待表单组件的 PerformClick 吗?

  • 772

我很难找到是否可以从另一个元素对 C# 表单元素执行虚拟单击,并等待其完成后再继续。

作为一个例子(不幸的是不完整),我想做的是

  private async void btn_my_Click(object sender, EventArgs e)
  {
      await Task.Run(() => radio_button_special.PerformClick()); // https://stackoverflow.com/q/14024963

      // once this is done, proceed with rest of processing
      do_rest_of_processing();
  }

当我在“调试运行”中单击按钮时,VS2019 会中断,并显示“InvalidOperationException:跨线程操作无效:从创建它的线程以外的线程访问控制‘radio_button_special’。”

但是,如果我只是在 Visual Studio 调试之外运行 exe,该按钮似乎可以工作(即我可以在应用程序中看到 radio_button_special.PerformClick() 首先完成,然后 do_rest_of_processing() 运行 - 并且我没有得到明确的异常像这样运行,所以它似乎按照我的想象工作)。

但这个异常让我害怕,所以我想摆脱它 - 我已经尝试过像这样的补救措施,我尝试从其他片段构建:

  private async void btn_my_Click(object sender, EventArgs e)
  {
      // first, I want to call the function otherwise called
      // when the radio button is clicked, and wait for it to complete
      radio_button_special.Invoke((MethodInvoker)async delegate
      {
          await Task.Run(() => radio_button_special.PerformClick()); // https://stackoverflow.com/q/14024963
      });
      // once this is done, proceed with rest of processing
      do_rest_of_processing();
  }

现在,这个函数已经在VS2019 IDE中给出了警告:

警告 CS1998:此异步方法缺少“等待”运算符,并将同步运行。考虑使用“await”运算符等待非阻塞 API 调用,或使用“await Task.Run(...)”在后台线程上执行 CPU 密集型工作。

...如果我调试运行该示例,我会得到堆栈跟踪:

System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   ...
   at System.Windows.Forms.Application.Run(Form mainForm)
   at my_test.Program.Main() in D:\work\bbs\BBS_DEV\BAPS_git\my_test\Program.cs:line 28

  This exception was originally thrown at this call stack:
    System.Windows.Forms.Control.Handle.get()
    System.Windows.Forms.Control.InternalHandle.get()
    System.Windows.Forms.Control.Update()
    System.Windows.Forms.ButtonBase.ResetFlagsandPaint()
    System.Windows.Forms.RadioButton.PerformClick()
    my_test.main_form.btn_my_Click.AnonymousMethod__122_1() in main_form.cs
    System.Threading.Tasks.Task.InnerInvoke()
    System.Threading.Tasks.Task.Execute()
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task)
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task)
    ...
    [Call Stack Truncated]

Inner Exception 1:
InvalidOperationException: Cross-thread operation not valid: Control 'radio_button_special' accessed from a thread other than the thread it was created on.

所以,基本上与之前的问题相同。

那么,我如何从另一个表单组件处理程序调用 C# 表单组件处理程序(例如单击)函数,等待它完成,然后调用另一个函数 - 而不会引发异常?

c#
  • 2 2 个回答
  • 21 Views

2 个回答

  • Voted
  1. Stephen Cleary
    2023-09-04T18:33:03+08:002023-09-04T18:33:03+08:00

    如果您只想从一种方法调用另一种方法,那么这可以工作:

    private void btn_my_Click(object sender, EventArgs e)
    {
      radio_button_special.PerformClick();
      do_rest_of_processing();
    }
    

    Task.Run队列工作到线程池,这在这里是不正确的。

    如果您有很长的工作要做,那么在线程池线程上运行该工作对您的用户来说会更好。在这种情况下,正确的解决方案是重构代码,以便有另一种方法可以通过单选按钮单击和此按钮单击来调用。

    • 1
  2. Best Answer
    jtxkopt
    2023-09-04T05:29:41+08:002023-09-04T05:29:41+08:00

    Task.Run将您提供的方法排队以在线程池线程上运行。因此,即使您执行调用,您仍然可以从另一个线程访问该控件。相反,您应该将Control.Invoke内部称为Task.Run.

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Run(() =>
        {
            radioButton1.Invoke(() => radioButton1.PerformClick());
        });
    }
    

    编辑:对 OP 海报有用的是:

    private async void button1_Click(object sender, EventArgs e)
    {
        await Task.Run(() =>
        {
            radioButton1.Invoke((MethodInvoker) delegate { radioButton1.PerformClick(); });
        });
    }
    
    • 0

相关问题

  • Polly DecorlatedJitterBackoffV2 - 如何计算完成所有重试所需的最长时间?

  • Wpf。在 ScrollViewer 中滚动 DataGrid

  • 我在使用 .NET MAUI MVVM 的游戏页面上获得的分数在其他页面上不可见。如何在本地设备中保存分数数据

  • 从 DataTemplate 内部将 TreeView 层次结构与 HierarchicalDataTemplate 结合使用

  • 如何改进 .NET 中的验证接口?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve