【问题标题】:Simple way to introduce async during a heavy loading op在重载操作期间引入异步的简单方法
【发布时间】:2014-03-23 09:20:38
【问题描述】:

我正在开发一个 WinForm 应用程序,该应用程序一开始就必须从云数据库中加载大量数据。这会导致空白表单出现长达 20 秒的挂起状态。我已经尝试了几种方法来使用基于 C++ 的加载屏幕来引导应用程序,但这些解决方案并不优雅,并且无法被团队领导接受。我经常使用 BachgroundWorker。这是我的代码:

private void ConfigurePWR_Load(object sender, EventArgs e)
{
    try
    {
        // Initializing logging (2-5 second delay)

        // Initializing security manager (3-7 second delay)

        // Load data from DB (10-30 second delay)
        ReloadData(0);
    }
    catch (Exception exp)
    {
        UiElements.ShowErrorMessageBox(this, "Loading failure. Cannot continue.", exp);
        Close();
    }      
}

private void ReloadData(byte caseSelector)
{
    switch (caseSelector)
    {
        case 0:
            LoadConnectors();
            LoadPolicies();
            LoadOrganizationDirectories();
            LoadProxyConfig();
            break;
        case 1:
            LoadConnectors();
            break;
        case 2:
            LoadPolicies();
            break;
        case 3:
            LoadOrganizationDirectories();
            break;
        case 4:
            LoadProxyConfig();
            break;
    }
}

现在,每个Load* 方法实际上都在为该BindingSource 分配一个数据源。因此,这就是对其中一个表单控件进行更改的地方。我正在尝试以一种在此处进行最少更改的方式来处理异步。

有推荐的方法吗?上次我尝试 Async-Await 时,我最终在 async-await 上编写了一个包装器,它在 async-await 上做得很好。它很快就会变得混乱。我不想重复这一点,因为我在表单代码中的几乎每个方法中都添加了 async 关键字。

【问题讨论】:

  • 返回一个Task怎么样?
  • 你能给我一个关于这方面的文章吗?
  • 我现在正在看一些。似乎 Task 方法遵循 return-a-thing 概念。我想要设置数据源并启用控件。我会尝试放置一个加载屏幕来阻止任何交互。只是不想要死掉的 UI。
  • 你不需要返回值,你不需要返回一个Task。像这样简单地添加异步不起作用? private async void ConfigurePWR_Load(object sender, EventArgs e)
  • @HassanGulzar Noseratio 在他的回答中写下了一切。

标签: c# winforms entity-framework async-await .net-4.5


【解决方案1】:

如果您的业务逻辑提供基于 Task 的异步 API,请使用它们。如果没有,请将其卸载到具有 Task.Run 的池线程以保持 UI 响应。如果同步操作需要大量时间,请使用 Task.Factory.StartNew w/ TaskCreationOptions.LongRunning 而不是 Task.Run。您可能也想观察取消。

我最近发布了一个 WinForms 应用程序的示例(这个概念本身并不特定于 WinForms):https://stackoverflow.com/a/22497438/1768303

【讨论】:

  • 我看到了代码,我相信它会起作用,并且应该作为初学者模板提供给任何刚接触异步和 TPL 的人。但是,当我正在将文本文件读取到 SQL 数据库时,我需要进行更多研究。我正在使用块。因此,从文本文件中逐行读取 200 行到代码内数据表中,然后在一个单独的方法中处理数据表,该方法具有提交语句并且只是杀死 UI。并继续从文本文件中读取直到下一个 200
  • @HassanGulzar,希望对您有所帮助。如果没有,请随时澄清任何观点。
  • 哦,确实有帮助。只是想知道我是否需要 Parallel.For,因为我正在阅读一个文本文件并使用 `File.ReadLines(_selectedDataFilePath).Count()' 来大致了解总记录。
  • @HassanGulzar,不,你不需要Parallel.For。它适用于计算密集型、受 CPU 限制的工作。 Task.Run 足以满足您的需求。
猜你喜欢
  • 2020-06-21
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2019-02-26
  • 2021-08-28
相关资源
最近更新 更多