单击WPF按钮时的方法运行不正常

时间:2015-06-13 00:00:34

标签: c# wpf

这是我的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
}

1 个答案:

答案 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;方法不能在一个单独的线程中运行,但是......因为代码示例远未完成,所以并没有真正说太多。如果您认为可能存在要解决的并发问题,请将您的问题示例缩减为一个良好的代码示例(请参阅我上面提供的链接),以充分说明这些问题,并发布一个专门询问这些问题的新问题。