Я создал границу и метку в пользовательском элементе управления. Когда окно загружается, он считывает список задач, которые должны выполняться из текстового файла, а затем создает одинаковое количество пользовательских элементов управления и добавляет его в панель стека.Выполнение потока зависает главный пользовательский интерфейс
<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 и ждет его закрытия. Но на этот раз мой главный пользовательский интерфейс зависает. Я хочу, чтобы основной пользовательский интерфейс был включен и анимация раскадровки, чтобы продолжить выполнение, показывая, что задача все еще выполняется. Как только задача будет завершена, я затем поставлю крест или галочку внутри пограничного элемента управления, указав, была ли операция успешной или неудачной. Почему главный пользовательский интерфейс висит?
'resetEvent.WaitOne()' блокирует поток пользовательского интерфейса до тех пор, пока не вызывается 'resetEvent.Set()'. – Clemens