C# WPF:异步进度条
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1152768/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: Asynchronous progress bar
提问by SumGuy
I'm trying to create a progress bar that will work asynchronously to the main process. I'm created a new event and invoked it however everytime I then try to perform operations on the progress bar I recieve the following error:
我正在尝试创建一个与主进程异步工作的进度条。我创建了一个新事件并调用它,但是每次我尝试在进度条上执行操作时,我都会收到以下错误:
"The calling thread cannot access this object because a different thread owns it"
“调用线程无法访问此对象,因为其他线程拥有它”
The following code is an attempt to send an instance of the progress bar to the event as an object, it obviously failed but it gives you an idea of what the code looks like.
以下代码尝试将进度条的实例作为对象发送到事件,它显然失败了,但它让您了解代码的外观。
private event EventHandler importing;
void MdbDataImport_importing(object sender, EventArgs e)
{
ProgressBar pb = (ProgressBar)sender;
while (true)
{
if (pb.Value >= 200)
pb.Value = 0;
pb.Value += 10;
}
}
private void btnImport_Click(object sender, RoutedEventArgs e)
{
importing += new EventHandler(MdbDataImport_importing);
IAsyncResult aResult = null;
aResult = importing.BeginInvoke(pbDataImport, null, null, null);
importing.EndInvoke(aResult);
}
Does anyone have ideas of how to do this.
有没有人知道如何做到这一点。
Thanks in advance SumGuy.
在此先感谢 SumGuy。
采纳答案by Arsen Mkrtchyan
You should use something like this
你应该使用这样的东西
pb.Dispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
if (pb.Value >= 200)
pb.Value = 0;
pb.Value += 10;
}
));
in your while loop
在你的 while 循环中
回答by cwap
You need to delegate pbDataImport to the dispatcher. Only the GUI-dispatcher can make changes to GUI controls :)
您需要将 pbDataImport 委托给调度程序。只有 GUI 调度程序可以更改 GUI 控件:)
回答by SumGuy
I've looked into it further and the asynchronous method will work as well as the following method from MSDN.
我进一步研究了它,异步方法与 MSDN 中的以下方法一样有效。
In XAML:
在 XAML 中:
<ProgressBar Width="100" Height="20" Name="progressBar1">
<ProgressBar.Triggers>
<EventTrigger RoutedEvent="ProgressBar.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="progressBar1" From="0" To="100" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ProgressBar.Triggers>
</ProgressBar>
In C#:
在 C# 中:
ProgressBar progbar = new ProgressBar();
progbar.IsIndeterminate = false;
progbar.Orientation = Orientation.Horizontal;
progbar.Width = 150;
progbar.Height = 15;
Duration duration = new Duration(TimeSpan.FromSeconds(10));
DoubleAnimation doubleanimation = new DoubleAnimation(100.0, duration);
progbar.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
My problem was that I was performing a stored procedure when I wanted the progress bar to perform and this holds the process up and therefore makes the progress bar a bit rubbish, even when asynchronous.
我的问题是,当我希望进度条执行时,我正在执行一个存储过程,这会阻止进程,因此即使是异步的,也会使进度条变得有点垃圾。
I suppose the other possiblilty would be to make the stored procedure actions asynchronous, what do you guys think?
我想另一种可能是使存储过程操作异步,你们怎么看?
Cheers, SumGuy
干杯,SumGuy
Edit (17 May 2010)
编辑(2010 年 5 月 17 日)
It seems a lot of people are interested in this post so I thought I'd add this. I found an excellent piece which describes Asynchronous work in WPF in great detail along with a tasty bit on progress bars:
似乎很多人对这篇文章感兴趣,所以我想我会添加这个。我找到了一篇很好的文章,它非常详细地描述了 WPF 中的异步工作以及进度条上的一些有趣内容:
回答by Rhyous
I like using MVVM and a BackgroundWorker a little bit better. Here is a sample of doing that.
我更喜欢使用 MVVM 和 BackgroundWorker。这是这样做的示例。
A Progress Bar using WPF's ProgressBar Control, BackgroundWorker, and MVVM