【问题标题】:Progress bar update in child thread not updating, Work done in main thread [duplicate]子线程中的进度条更新未更新,主线程中完成的工作[重复]
【发布时间】:2020-10-31 03:42:22
【问题描述】:

我有一个应用程序,它有一个 C# 前端(GUI 客户端)和一个 C++ 后端(业务逻辑)。后端负责请求进度条功能,并通过发出前端有观察者委托来响应和采取行动的事件来做到这一点。所以事件在主线程中被调度和响应。

我想生成第二个线程来显示和更新进度条,因为主线程被后端占用。虽然我可以在应该显示进度条窗口并在完成后正确隐藏,但它不会响应更新/增量。

ProgressBarWindow 持有进度条控件 (pBar)。 ProgressBarWindowprogressBarThread 所有。

public static EventObserver.ProgressBeginEvent pbe = null;
public static EventObserver.ProgressFinishEvent pfe = null;
public static EventObserver.ProgressIncrementEvent pie = null;
public static Thread progressBarThread = null;

static private void InitialiseProgressBarManager()
{

    // Setup the progress bar callbacks...
    pbe = new EventObserver.ProgressBeginEvent(delegate
        (int currentIncrements, int totalIncrements, string message)
    {
        // Create the thread and progress bar window...
        progressBarThread = new Thread(() =>
        {
            ProgressBarWindow sw = new ProgressBarWindow();
            sw.pBar.IsIndeterminate = false;
            sw.pBar.Minimum = currentIncrements.Value;
            sw.pBar.Maximum = totalIncrements.Value;
            sw.pBar.Value = 0;
            sw.Show();

            pie = new EventObserver.ProgressIncrementEvent(delegate ()
            {
                sw.pBar.Value++;        // The calling thread cannot access this object... see below 
            });

            pfe = new EventObserver.ProgressFinishEvent(delegate ()
            {
                progressBarThread.Abort();
                progressBarThread = null;
            });
        });

        progressBarThread.SetApartmentState(ApartmentState.STA);
        progressBarThread.IsBackground = true;
        progressBarThread.Start();
    });
}

窗口按预期显示,ProgressIncrementEvent 被正确引发(它归线程所有),但是当它尝试访问该值时出现异常。

The calling thread cannot access this object because a different thread owns it.

我需要互斥锁或其他锁吗?我希望观察者委托的范围将允许委托对线程本地 ProgressBarWindow 进行可变访问,即使它是从主线程调用的?

我不是一个出色的 C# 开发人员,更不用说 C# 线程,所以我对我应该在这里做什么或者即使我能实现这种行为有点卡住了。任何帮助或指导来完成这项工作将不胜感激。

P.S 我正在使用 WPF,其中 ProgressBarWindow 是在 XAML 中定义的。

【问题讨论】:

  • GUI 应用程序中的主线程是 UI 线程。你不应该在 UI 线程上做艰苦的工作。相反,产生一个工作线程并在那里努力工作。让您的主 (UI) 线程只进行 GUI 更新并启动另一个工作线程。
  • @MickyD 非常相似,我确实看到了,但是它没有提到具有 GUI 控件的子线程,我认为这可能是我的问题。可能需要稍微重新设计,因为不确定前端如何决定是否在后台执行操作。非常感谢。

标签: c# wpf multithreading progress-bar


【解决方案1】:

尝试使用窗口的调度程序访问控件:

sw.Dispatcher.BeginInvoke(new Action(() => sw.pBar.Value++));

【讨论】:

  • 是否有另一个官方ProgressBar 拥有IsIndeterminate 属性?
  • @MickyD 抱歉没有提及,我正在使用 WPF,是的,ProgressBarWindow 有一个名为 ProgressBar 的成员 pBar。已更新。
  • @MickyD: 不是。pBar 是窗口中的ProgressBar...
  • “pBar 是窗口中的 ProgressBar” - 哦,我的错。米奇的另一种杜松子酒和滋补品。 +1
  • @MickyD 同意,我觉得 atm 的方式我现在可以用其中的一些来做...... ;)
猜你喜欢
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 2018-03-29
相关资源
最近更新 更多