这是我的XAML部分代码:
<DockPanel Margin="1 5 1 0" Height="25">
<Button DockPanel.Dock="Right" Width="70" Margin="6 0 0 0" Content="Install" Click="Install" />
<Button DockPanel.Dock="Right" Width="70" Margin="6 0 0 0" Content="Uninstall"/>
<ProgressBar Name="progressBar"/>
</DockPanel>
这是Install方法:
private void Install(object sender, RoutedEventArgs e)
{
progressBar.Value = 5;
installer.InstallProgram1();
progressBar.Value = 25;
installer.InstallProgram2();
progressBar.Value = 50;
installer.InstallProgram3();
progressBar.Value = 75;
installer.InstallProgram4();
progressBar.Value = 100;
}
当我单击安装按钮时,它会运行Install方法但不正确。
- 它从不执行第一行:'progressBar.Value = 5'
- 第二行运作良好
- 没有任何作用。
我尝试用'MessageBox.Show(“Hello World”)替换我的方法,它有效,进度条值会改变。
但是为什么它不适用于我的方法?
为什么'installer.InstallProgram2()'无效/完成?
我的两种方法,它们位于Installer.cs文件中:
public void InstallProgram1()
{
// Download the lavfilters executable.
var url = "http://www.videohelp.com/software/LAV-Filters";
var selector = "a.linktool:nth-child(12)";
var filename = downloader.DownloadFromVideoHelp(url, selector);
// TODO: Installation
}
public void InstallProgram2()
{
// Download the madVR archive
var url = "http://www.videohelp.com/software/madVR";
var selector = ".linktool";
var filename = downloader.DownloadFromVideoHelp(url, selector);
// TODO: Installation
}
答案 0 :(得分:4)
如果没有a good, minimal, complete code example,就无法确定解决问题的最佳方法。但是可以提供一些建议来帮助。
首先,你写道:
它永远不会执行第一行:&#39; progressBar.Value = 5&#39;。
这简直是假的。调试器会告诉你多少。只有在执行剩余时才会跳过方法中的第一个语句。
至于方法中的其余陈述,也许它们有效,也许它们不适用。再说一次,缺少一个完整的代码示例,Stack Overflow的任何人都无法对此发表评论。
我可以告诉你的是,你发布的代码将显示,好像分配progressBar.Value
的语句没有被执行,因为你正在执行这些语句UI线程,阻止该线程在整个方法完成之前进行任何屏幕更新。
all 可能是您的代码错误。如果是这样,改变你的方法,使它看起来更像这个应该有帮助:
private async void Install(object sender, RoutedEventArgs e)
{
progressBar.Value = 5;
await Task.Run(() => installer.InstallProgram1());
progressBar.Value = 25;
await Task.Run(() => installer.InstallProgram2());
progressBar.Value = 50;
await Task.Run(() => installer.InstallProgram3());
progressBar.Value = 75;
await Task.Run(() => installer.InstallProgram4());
progressBar.Value = 100;
}
以上操作是运行您的各种&#34;安装程序&#34;单独线程中的方法。它使用新的(从.NET 4.5开始)async
/ await
功能来简化UI线程和任务之间的交互。方法本身中的所有代码仍然在UI线程中执行,但是(现在)匿名方法调用您的&#34;安装程序&#34;方法是使用线程池执行的。
C#在每个Install()
语句中从await
方法返回,允许UI线程继续正常运行(例如,更新UI以反映ProgressBar
的新值)。当每个任务完成后,控制将在该任务的Install()
语句之后返回await
方法;重复此过程,直到方法达到其正常返回点(例如return
语句,或者,如此处,方法体的结尾)。
请注意在不同线程中执行代码的常见缺陷。您发布的代码示例中没有任何内容可以表明&#34;安装程序&#34;方法不能在一个单独的线程中运行,但是......因为代码示例远未完成,所以并没有真正说太多。如果您认为可能存在要解决的并发问题,请将您的问题示例缩减为一个良好的代码示例(请参阅我上面提供的链接),以充分说明这些问题,并发布一个专门询问这些问题的新问题。