【发布时间】:2020-10-31 03:42:22
【问题描述】:
我有一个应用程序,它有一个 C# 前端(GUI 客户端)和一个 C++ 后端(业务逻辑)。后端负责请求进度条功能,并通过发出前端有观察者委托来响应和采取行动的事件来做到这一点。所以事件在主线程中被调度和响应。
我想生成第二个线程来显示和更新进度条,因为主线程被后端占用。虽然我可以在应该显示进度条窗口并在完成后正确隐藏,但它不会响应更新/增量。
ProgressBarWindow 持有进度条控件 (pBar)。
ProgressBarWindow 归 progressBarThread 所有。
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