c# - 管理 .NET WinForm 应用程序中的线程

标签 c# .net winforms multithreading user-interface

这是我的目标:该应用程序由一个表单 - MainForm - 组成,其中包含许多选项卡(类似于 Notepad++ GUI)。每个选项卡都是一个 UserControl 后代 (UCDx)。 MainForm 可以显示 2 个或更多包含相同 UCDx 实例的选项卡。目标是 UCDx 必须执行一些耗时的操作或方法执行 - 即数据库读/写、Web 服务方法调用。我希望在单独的线程中运行此类操作,以免卡住 UI。此外,我还需要实现一个信息表单(InfoForm) - 它将显示当前运行线程的信息,并具有一些交互功能 - 即关闭运行时间过长的线程。

我面临的主要问题是:

  • 与 GUI 的线程交互 - 即线程读取应显示在网格中的数据;
  • 线程交互管理 - 在实现 InfoForm 时。

在并发/并行编程中,我是初学者 - 有人可以提供一些关于如何实现它的线索吗?

最佳答案

我首先将工作逻辑与 UI 分开。

例如,对于“需要读取数据并显示数据的线程”,请尝试将问题分成更小的部分:

  1. 创建一个普通类,它具有同步处理方法,不涉及线程。像这样的东西:

    interface IServiceReader
    {
         Data GetDataFromService(IServiceInfo info);
    }
    
  2. 测试一下。创建单元测试,甚至是一个小型控制台应用程序,您可以在其中看到它在没有 GUI 的情况下也能正常工作。

  3. 创建一个异步包装类,它调用 ServiceReader 来完成这项工作,但在后台线程上调用它,并在完成后触发一个事件。

    interface IAsyncServiceReader
    {
         void Start(IServiceInfo info);
         event EventHandler<Data> DataReceived;
    }
    
  4. 再次测试一下。这应该是一个单独的类库,独立于您的 GUI。

  5. 使用 MVC 或类似模式将 View (选项卡)与模型(异步服务读取器)分开。这意味着您应该从 View 中触发交互事件,在 Controller 中处理它们,然后让 Controller 在模型中调用适当的操作:

    class Controller
    {
         readonly ITabView _view; 
         readonly IAsyncServiceReader _model;
         public Controller(ITabView view, IAsyncServiceReader model)
         {
              _view = view; _model = model;
              AttachHandlers();
         }
    
         void AttachHandlers()
         {
              view.UserRequestedLoading += (sender,info) => model.Start(info);
              model.DataReceived += (sender,data) => view.DisplayData(data);
         }
    }
    
  6. 最后,确保后台线程调用被分派(dispatch)到正确的 (GUI) 线程。这仅仅意味着您的选项卡 View 需要检查是否需要调用:

    class TabView : UserControl
    {
         void DisplayData(Data data)
         {
             if (this.InvokeRequired)
             {
                 BeginInvoke(new Action<Data>(DisplayData), data);
                 return;
             }
    
             // otherwise, display the data in some way
             dataGrid.DataSource = data; ...
         }
    }
    

将模型与 View 分离将简化测试以及以后对 UI 的更改。您可以决定将其设为控制台应用程序或 Windows 服务,这将使您的业务逻辑保持完整。

关于c# - 管理 .NET WinForm 应用程序中的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7834378/

相关文章:

c# - 阅读下面的 xml 显示 c# 中的错误

c# - 设置内容边框的圆角半径

c# - 如何使用 emgu cv 捕获视频流

c# - 表格的宽度不能小于 140 像素。为什么?

c# - 如何删除时间并仅在 RDLC 中显示日期

c# - 什么是 |和 ^ 运算符用于什么?

c# - White UI Automation库如何使用CaSTLe DynamicProxy?

c# - 在静态方法中使用语句/调用 Dispose

.net - String.Split 不删除拆分文本,仅删除第一个字母

c# - 如何刷新屏幕以使关闭的表单真正消失