gpt4 book ai didi

c# - 使用后台线程显示 "Busy Indicator"

转载 作者:太空宇宙 更新时间:2023-11-03 10:50:23 29 4
gpt4 key购买 nike

我在主线程上做一些繁重的计算,这些计算不能在单独的线程上运行。

我想在这些计算运行时在应用程序 UI 上显示一个“忙碌指示器”(即旋转小部件)。因此,我无法在主线程上显示繁忙指示器,因为在这些计算运行时 UI 被锁定。

为了解决这个问题,我尝试将忙碌指示器移动到单独的线程。在this post的帮助下我可以将忙碌指示器放在单独的线程上。但是,我无法与该线程通信以启动或停止忙碌指示器。

     private HostVisual CreateBusyIndicatorOnWorkerThread()

{
// Create the HostVisual that will "contain" the VisualTarget
// on the worker thread.
HostVisual hostVisual = new HostVisual();
Thread thread = new Thread(new ParameterizedThreadStart(BusyIndicatorWorkerThread));
thread.ApartmentState = ApartmentState.STA;
thread.IsBackground = true;
thread.Start(hostVisual);
// Wait for the worker thread to spin up and create the VisualTarget.
s_event.WaitOne();
return hostVisual;
}

private static AutoResetEvent s_event = new AutoResetEvent(false);
private void BusyIndicatorWorkerThread(object arg)

{
// Create the VisualTargetPresentationSource and then signal the
// calling thread, so that it can continue without waiting for us.
HostVisual hostVisual = (HostVisual)arg;
VisualTargetPresentationSource visualTargetPS = new VisualTargetPresentationSource(hostVisual);
s_event.Set();

// Create a MediaElement and use it as the root visual for the
// VisualTarget.
visualTargetPS.RootVisual = CreateBusyIndicator();

// Run a dispatcher for this worker thread. This is the central
// processing loop for WPF.
System.Windows.Threading.Dispatcher.Run();
}

private FrameworkElement CreateBusyIndicator()

{
var busyIndicator = new MyBusyIndicator();
//busyIndicator.DataContext = this.
Binding myBinding = new Binding("IsBusy");
myBinding.Source = this;
busyIndicator.SetBinding(MyBusyIndicator.IsBusyProperty, myBinding);
}

我总是得到一个异常“调用线程无法访问这个对象,因为另一个线程拥有它”。这是因为我试图从主线程更新繁忙指示器,而繁忙指示器由另一个线程拥有。

我也尝试过 this article 中给出的方法,

private void CreateAndShowContent()
{
Dispatcher = Dispatcher.CurrentDispatcher;
VisualTargetPresentationSource source =
new VisualTargetPresentationSource(_hostVisual);
_sync.Set();
source.RootVisual = _createContent();
DesiredSize = source.DesiredSize;
_invalidateMeasure();

Dispatcher.Run();
source.Dispose();
}

但是使用这种方法 Dispatcher.Run() 直到计算完成之后才会发生任何事情,然后显示忙碌指示符。

我想从主线程与具有繁忙指示器的线程进行通信。有没有人有办法?

最佳答案

没有理由在 UI 线程中运行“繁重的计算”。更重要的是 - 这是一种不好的做法。取而代之的是使用 BackgroundWorker 它将起作用,同时事件的 UI 线程将显示 Loading/Calculating:

var worker = new BackgroundWorker();

worker.DoWork += (s, e) => {
// This part will last at a separate thread without blocking UI.
// Excellent place for heavy computations.
}

worker.RunWorkerCompleted += (s, e) => {
// Here we're back to UI thread - so you can change states and stop animations.
}

// And finally start async computation
worker.RunWorkerAsync();

UI 应包含 BusyIndi​​cator 控件,当您开始/完成 worker 时,它将被激活/停止

关于c# - 使用后台线程显示 "Busy Indicator",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21630834/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com