执行线程挂起主UI
本文关键字:UI 挂起 线程 执行 | 更新日期: 2023-09-27 18:04:54
我在用户控件中创建了一个边框和一个标签。当窗口加载时,它从文本文件中读取要执行的任务列表,然后创建相同数量的用户控件并将其添加到堆栈面板。
<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>
Border有一个动画,可以在任务执行时将背景颜色从白色更改为绿色。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();
}
当我只是运行应用程序而不执行任务时,它工作良好,故事板动画工作正常。但是使用这段代码,在doSomeWork方法中,它启动notepad.exe并等待它关闭。但这次我的主界面挂起了。我希望主UI是启动的,故事板动画继续运行,表明任务仍在执行。任务完成后,我将在边界控件中放置一个叉号或勾号图像,指示操作是成功还是失败。为什么主UI挂起了?
如果您希望在等待流程完成时保持UI活动,则应该订阅Exited
事件。
process.Exited += new EventHandler(OnProcessExited);
process.Start();
和事件。
private void OnProcessExited(object sender, System.EventArgs e)
{
//TODO
}