执行线程会挂起主UI

时间:2015-07-27 08:22:18

标签: c# wpf multithreading

我在用户控件中创建了边框和标签。当窗口加载时,它会从文本文件中读取要执行的任务列表,然后创建相同数量的用户控件并将其添加到堆栈面板。

<UserControl x:Class="DiagnoseTool.TaskControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="30" d:DesignWidth="515" Height="40">
<UserControl.Resources>
    <Storyboard x:Key="ShowBlink">
        <ColorAnimation From="White" To="LightGreen" Duration="0:0:0.5" Storyboard.TargetName="StatusRectangle" Storyboard.TargetProperty="Background.Color" AutoReverse="True" RepeatBehavior="Forever"/>
        <!--ColorAnimation From="LightGreen" To="White" Duration="0:0:1" Storyboard.TargetName="StatusRectangle" Storyboard.TargetProperty="Background.Color"/-->
    </Storyboard>
</UserControl.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.08*"></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Border x:Name="StatusRectangle" Margin="5" Grid.Column="0" Background="White" Width="20" Height="20" BorderThickness="1" BorderBrush="Black"></Border>    
    <Label x:Name="TaskNameLabel" Grid.Column="1" Margin="5" FontSize="12" Content="" FontFamily="Calibri"></Label>
</Grid>

边框有一个动画,可在执行任务时将背景颜色从白色更改为绿色。 taskcontrol后面的代码包含一个方法:

/// <summary>
    /// This function is used to perform some task
    /// </summary>
    /// <returns></returns>
    public bool StartShowingProgress()
    {
        bool bRet = true;
        try
        {
            sbdStatusDisplay = (Storyboard)FindResource("ShowBlink");
            sbdStatusDisplay.Begin(this, true);
        }
        catch (Exception ex)
        {
            bRet = false;
        }
        return bRet;
    }

主窗口加载的事件处理程序是:

 private void MainWindowLoaded(object sender, RoutedEventArgs e)
    {
        for(int i=0;i<taskList.Count;i++)
        {
            Logger.WriteToLog(taskList[i].TASKNAME);
            TaskControl objTaskControl = new TaskControl(taskList[i].TASKNAME);
            TasksPanel.Children.Add(objTaskControl);
        }

        for (int i = 0; i < taskList.Count; i++)
        {
            (TasksPanel.Children[i] as TaskControl).StartShowingProgress();

            Thread th = new Thread(doSomeWork);
            th.Start(i);
            resetEvent.WaitOne();
        }
    }

doSomeWork方法代码是:

       private void doSomeWork(object val)
    {
        int index = (int)val;
        Utilities.StartProcess(taskList[index].TASKFILE, taskList[index].TASKARGUMENT, taskList[index].CHECKRETURNVALUE);
        resetEvent.Set();
    }

StartProcess代码是:

 Process process = new Process();
            // Configure the process using the StartInfo properties.
            process.StartInfo.FileName = fileToRun;
            process.StartInfo.Arguments = arguments;
            process.Start();
            //Check if we need to wait for the process to exit
            if (waitForExit)
            {
                process.WaitForExit();
            }

当我只运行应用程序而不执行任务时,它工作正常,故事板动画正常工作。但是使用此代码,在doDoomeWork方法中,它会启动notepad.exe并等待它关闭。但这次我的主用户界面挂了。我希望主UI完成,故事板动画继续运行,表明任务仍在执行。任务完成后,我会在边框控件内放置一个十字或刻度图像,指示操作是成功还是失败。为什么主UI悬空?

1 个答案:

答案 0 :(得分:1)

如果您希望在等待流程完成时保持UI处于活动状态,则应订阅Exited事件。

process.Exited += new EventHandler(OnProcessExited);
process.Start();

事件。

private void OnProcessExited(object sender, System.EventArgs e)
{
    //TODO
}