winforms:使用parallel.foreach更新进度

2024-03-24

我没有看到任何与我的问题相关的帖子,因此,如果我发布已经提出的问题,我深表歉意。

我有一个 Windows 窗体程序,C#,用于检查股票并进行分析。主窗体通过新线程和 ShowDialog 启动另一个窗体。当它加载时,它正在运行parallel.foreach。在该parallel.foreach 中,我想显示主窗体的进度。

我遇到了跨线程问题,并添加了调用,尽管它似乎不是线程安全的,因为它似乎在 parallel.foreach 的末尾陷入死锁。我尝试过代表、活动,但没有成功。帮助我,欧比旺,你是我唯一的希望!

精简版本:

主要形式

private void button1_Click(object sender, EventArgs e)
    {
        YearLows yearLows = new YearLows();
        Thread yearLowsThread = new Thread(() => StartYearLows(yearLows));
        yearLowsThread.Start();
        btnGetYearLows.Enabled = false;
    }

    private void StartYearLows(YearLows yearLows)
    {
        yearLows.ShowDialog();
    }

    public void UpdateProgress(string text)
    {
        lblProgress.Text = text;
    }

第二种形式对话框

    public partial class YearLows : Form
    {
        private void YearLows_Load(object sender, EventArgs e)
        {
            // work
            Parallel.ForEach(responseStocks, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, x =>
            {
              // more work
              Interlocked.Increment(stocksProcessed);
              UpdateProgress($"{stocksProcessed} / {stocksTotal} Researched");
            });
        }

        private void UpdateProgress(string text)
        {
            Invoke(new Action(() => frmMain.UpdateProgress(text)));
        }
    }

更新1: 如果我将进度更新标签移至子窗体,则似乎我正在获取所有进度更新。我必须从 Load 事件移动到 Shown 事件,以便呈现表单,以便用户可以看到进度更新。不过,我必须遵循 SLAks 的建议并运行 Task.Run(() => Parallel.ForEach。这对我有用。如果我想要主进程上的进度更新,我仍然想弄清楚为什么它仍然锁定到最后(我总是读到 async void 很糟糕,但我想在 winforms 中这些定义的方法签名中没有办法解决这个问题)

    public partial class YearLows : Form
    {
        private async void YearLows_Shown(object sender, EventArgs e)
        {
            await AnalyzeStocks();
        }

        private async Task AnalyzeStocks(object sender, EventArgs e)
        {
            // work
            await Task.Run(() => Parallel.ForEach(responseStocks, new ParallelOptions { MaxDegreeOfParallelism = MaxThreads }, x =>
            {
                // more work
                Interlocked.Increment(stocksProcessed);
                UpdateProgress($"{stocksProcessed} / {stocksTotal} Researched");
            }));
        }

        private void UpdateProgress(string text)
        {
            Invoke(new Action(() => lblProgress.UpdateProgress(text)));
        }
    }

Parallel.ForEach是一个阻塞调用;它也在调用线程上运行委托。因此,UI 在完成之前无法更新。

相反,你应该使用await with Task.WhenAll(如果您正在进行异步工作)或Task.Run(() => Parallel.ForEach(...))(如果它受 CPU 限制),以便让 UI 线程保持空闲并能够更新。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

winforms:使用parallel.foreach更新进度 的相关文章

  • 在 C# 中按元素相乘数组具有意想不到的性能

    我想找到按元素相乘两个数组的最佳方法 这是更广泛项目的一部分 其中性能而不是唯一的考虑因素 我今天开始用 C Linqpad 编写一些函数 因此它还没有以任何方式进行优化 下面代码的输出如下 Environment ProcessorCou
  • FileStream 构造函数和默认缓冲区大小

    我们有一个使用 NET 4 用 C 编写的日志记录类 我想添加一个构造函数参数 该参数可以选择设置文件选项 WriteThrough http msdn microsoft com en us library system io fileo
  • 为什么在创建矩阵类时使用向量不好?

    对于我的矩阵类 我做了 template
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • Android 为什么这不会抛出错误的线程异常?

    我的印象是视图只能从主线程操作 但是 为什么这不会崩溃 public class MainActivity extends Activity TextView tv Override protected void onCreate Bund
  • 为什么 set_symmetry_difference 无法与比较器一起使用?

    Example program include
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 将二进制数据从 C# 上传到 PHP

    我想将文件从 Windows C 应用程序上传到运行 PHP 的 Web 服务器 我知道 WebClient UploadFile 方法 但我希望能够分块上传文件 以便我可以监控进度并能够暂停 恢复 因此 我正在读取文件的一部分并使用 We
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6
  • 您是否将信息添加到每个 .hpp/.cpp 文件的顶部? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 创建新的 C 头文件 源文件时 您会在顶部添加哪些信息 例如 您是否添加日期 您的姓名 文件描述等 您是否使用结构化格式来存储此信息 e g F
  • C++ Streambuf 方法可以抛出异常吗?

    我正在尝试找到一种方法来获取读取或写入流的字符数 即使存在错误并且读 写结束时间较短 该方法也是可靠的 我正在做这样的事情 return stream rdbuf gt sputn buffer buffer size 但如果streamb
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft

随机推荐