【发布时间】:2015-06-07 21:02:12
【问题描述】:
在我的 WPF 程序中,它需要大量的处理时间并长时间冻结。
所以我决定使用后台工作者并在后台处理它。
但它不起作用。通过调试,程序停在Render3D()。它不会抛出异常。就像你输入return一样。
换句话说,它在到达Render3D() 后什么都不做,只会返回。
(我不是说它会返回,因为我不确定但行为与返回相同)
private readonly BackgroundWorker backgroundWorker = new BackgroundWorker();
private AssetDeclaration _assetDeclaration = new AssetDeclaration();
public MainWindow()
{
backgroundWorker.DoWork += backgroundWorker1_DoWork;
backgroundWorker.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 1000; i++)
{
if (!((BackgroundWorker)sender).CancellationPending)
{
Render3D(); // will return at this point. (why?) or waiting for something to start?
((BackgroundWorker)sender).ReportProgress(i);
}
else
{
e.Cancel = true;
break;
}
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done!");//will show message box instant.
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar1.Value = e.ProgressPercentage;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//...Some work here before starting Hard job!
//...From now i want to start heavy process in background.
//...with report to progress bar at same time.
backgroundWorker.RunWorkerAsync(100);
}
Render3D() 在没有后台处理的情况下可以正常工作,但会冻结一段时间。
Render3D() 属于Partial 的MainWindow 类。因为有很多方法,所以我决定将它们分开。
另外,我如何在 backgroundWorker1_DoWork 之外使用 ReportProgress 。例如在 Render3D() 中。
最后一件事:我想知道如何向用户展示完成了多少流程。
已解决!
问题是因为我在Render3D() 中设置了Viewport3D
我将它从 Render3D 中分离出来,问题得到了解决。感谢 Henk Holterman 的正确答案。
似乎有些任务无法在另一个线程中完成。通过错误报告,我发现无效任务正在设置 Viewport3D 属性。
此任务必须在主线程中完成。
以下是导致后台工作人员停止运行的无效代码。
DefineCamera();
Viewport.Children.Add(model); // Must be run in Main thread.
还有这部分。
private void DefineCamera()
{
PerspectiveCamera camera = new PerspectiveCamera
{
FieldOfView = 60
};
PositionCamera(camera);
Viewport.Camera = camera; // Must be run in Main thread.
}
【问题讨论】:
-
您没有 Completed 事件。添加它并处理传入的
e.Error。或者只是向 DoWork 添加一个 try/catch。您现在忽略了可以告诉您出了什么问题的异常。 -
"在我添加 RunWorkerCompleted 之后" 好的,现在让它报告
e.Error。 -
好的,Render3D() 不适合在线程上运行。运动结束。
-
我们不能评论/分析我们看不到的代码。 ViewPort 使用起来不安全。也许你可以拆分 GUI / 非 GUI 代码,我不知道。
-
+1 谢谢。生病尝试拆分非 GUI 部分。绘图模型只需要几毫秒。所以这可能会解决问题@HenkHolterman
标签: c# wpf backgroundworker