0

我有一个用 C# 编写的课程。在其中,我想在列表上并行运行某个函数。在每个项目完成后,我想更新一个进度条。但是,我从我的程序中得到了非常奇怪的行为。它执行事件并到达我的子程序,但从未继续实际执行任何代码。相反,它只是冻结。(我混合了 vb.net 和 c#。它会在某个时候被重写)

所以在我的 Windows 窗体中,我调用

    progressBar.Visible = True
    progressBar.Value = 0
    progressBar.Maximum = dataGrid.SelectedRows.Count

    AddHandler quoteManager.refreshStarted, AddressOf progressBarCounter
    quoteManager.refreshAllAsync(list)

事件很简单

Private Sub progressBarCounter()
    Me.Invoke(Sub()
                  If progressBar.Value = progressBar.Maximum Then
                      progressBar.Visible = False
                  Else
                      progressBar.Value += 1
                  End If
              End Sub)
End Sub

在报价管理器类中我定义了这个。

    public event Action refreshStarted;

    public void refreshAllAsync(List<BindableQuote> bindableQuotes)
    {
        bindableQuotes.AsParallel()
            .WithDegreeOfParallelism(10)
            .ForAll((quote) => {
                quote.refreshAll();
                if (refreshStarted != null) { refreshStarted(); }
            });
    }

所以出于某种原因,我让它在列表中的每个项目上输入progressBarCounter,但它永远不存在。相反,它只是保持表单冻结。

4

2 回答 2

0

这里似乎发生的是您从多个线程访问 UI 对象。

这是不支持的。您必须在工作线程上运行此代码,并让它以某种方式累积进度,并将消息发送回 UI 线程。该类BackgroundWorker可以帮助您实现对 UI 线程的编组。

于 2010-11-26T20:10:53.470 回答
0

我不确定这是怎么回事,但看起来progressBarCounter 正在阻塞,因为您正在调用Invoke。您应该改用 BeginInvoke 吗?使用 BeginInvoke 可能会解决死锁问题。请参阅这篇文章:Invoke() 和 BeginInvoke() 有什么区别

于 2010-11-26T20:25:51.567 回答