如何在不停止 WPF 中的计时器的情况下使用线程使用进程?
How to use process using Threads without stoping a timer in WPF?
这是一个小指南,可帮助解决计时器在使用默认应用程序打开文件时停止的问题。
如果您在 C# WPF 中使用计时器,您会注意到计时器将停止工作,直到文件关闭,这可能不是您想要的行为。
例如,假设您希望在要向用户显示的文件打开时立即启动计时器。当用户看到或阅读您希望计时器继续的文件时。如果不使用线程,计时器将不会继续工作,直到文件关闭。
遇到的问题是这样的:
我有一个计时器,它通过按下按钮 (btnTache1) 启动,但是当我使用 System.Diagnostics.Process 使用另一个按钮 (btnVideo1) 使用默认应用程序打开文件时它会停止。它只会在文件关闭后恢复。
这是程序组件的简要说明:
有一个按钮可以显示名为 btnVideo1 的媒体
按钮的 onclick 事件定义了计时器 _timer1 和要向用户显示的文件 _media1 以及计时器使用的倒计时 _startingTimer1 设置为 30 秒。
代码如下:
private int _startingTimer1;
private string _media1;
DispatcherTimer _timer1 = new DispatcherTimer();
private void btnVideo1_Click(object sender, RoutedEventArgs e)
{
_startingTimer1 = 30; // 30 seconds
// stop timer if already started
if (_timer1.IsEnabled == true)
{
_timer1.Stop();
}
// configure timer
_timer1 = new DispatcherTimer();
_timer1.Interval = TimeSpan.FromSeconds(1);
_timer1.Tick += timer_Tick1;
_timer1.Start();
// defining the file to show to the user
string procedure = "procedure1.mp4"
_media1 = "//10.10.0.1/Procedures/ + procedure;
ShowVideo(_media1);
}
// Action done when a tick for timer occur
private void timer_Tick1(object sender, EventArgs e)
{
// decreasing countdown
_startingTimer1--;
// calculate and show the timer (countdown)
TimeSpan time = TimeSpan.FromSeconds(_startingTimer1);
tbxTemps1.Text = time.ToString();
// if timer under 0
if (_startingTimer1 < 0)
{
// change background color depending on number
if (_startingTimer1 % 2 == 0)
btnTemps1.Background = new SolidColorBrush(Colors.OrangeRed);
else
btnTemps1.Background = new SolidColorBrush(Colors.LightGray);
}
}
// show the file to the user
private void ShowVideo(string media)
{
try
{
// define a process to show the file
System.Diagnostics.Process process = new System.Diagnostics.Process();
// declare the path to the file
process.StartInfo.FileName = new Uri(media, UriKind.Absolute).ToString();
process.StartInfo.UseShellExecute = true;
// start the process to show the file to the user
process.Start();
process.WaitForExit();
}
catch
{
MessageBox.Show("Could not open the file.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
要解决这个问题,线程的使用确实很方便。使用线程调用函数使计时器在主线程中继续,而其他事情在另一个线程中并行完成。为实现这一点,这就是我所做的更改。
我更改了 ShowVideo 方法如下:
private void ShowVideo(string media)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = new Uri(media, UriKind.Absolute).ToString();
process.StartInfo.UseShellExecute = true;
Thread showFile = new Thread(() => process.Start());
showFile.Start(); // start the Thread
showFile.Join();
showFile.WaitForExit();
}
catch
{
MessageBox.Show("Could not open the file.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
这是一个小指南,可帮助解决计时器在使用默认应用程序打开文件时停止的问题。
如果您在 C# WPF 中使用计时器,您会注意到计时器将停止工作,直到文件关闭,这可能不是您想要的行为。
例如,假设您希望在要向用户显示的文件打开时立即启动计时器。当用户看到或阅读您希望计时器继续的文件时。如果不使用线程,计时器将不会继续工作,直到文件关闭。
遇到的问题是这样的: 我有一个计时器,它通过按下按钮 (btnTache1) 启动,但是当我使用 System.Diagnostics.Process 使用另一个按钮 (btnVideo1) 使用默认应用程序打开文件时它会停止。它只会在文件关闭后恢复。
这是程序组件的简要说明: 有一个按钮可以显示名为 btnVideo1 的媒体 按钮的 onclick 事件定义了计时器 _timer1 和要向用户显示的文件 _media1 以及计时器使用的倒计时 _startingTimer1 设置为 30 秒。
代码如下:
private int _startingTimer1;
private string _media1;
DispatcherTimer _timer1 = new DispatcherTimer();
private void btnVideo1_Click(object sender, RoutedEventArgs e)
{
_startingTimer1 = 30; // 30 seconds
// stop timer if already started
if (_timer1.IsEnabled == true)
{
_timer1.Stop();
}
// configure timer
_timer1 = new DispatcherTimer();
_timer1.Interval = TimeSpan.FromSeconds(1);
_timer1.Tick += timer_Tick1;
_timer1.Start();
// defining the file to show to the user
string procedure = "procedure1.mp4"
_media1 = "//10.10.0.1/Procedures/ + procedure;
ShowVideo(_media1);
}
// Action done when a tick for timer occur
private void timer_Tick1(object sender, EventArgs e)
{
// decreasing countdown
_startingTimer1--;
// calculate and show the timer (countdown)
TimeSpan time = TimeSpan.FromSeconds(_startingTimer1);
tbxTemps1.Text = time.ToString();
// if timer under 0
if (_startingTimer1 < 0)
{
// change background color depending on number
if (_startingTimer1 % 2 == 0)
btnTemps1.Background = new SolidColorBrush(Colors.OrangeRed);
else
btnTemps1.Background = new SolidColorBrush(Colors.LightGray);
}
}
// show the file to the user
private void ShowVideo(string media)
{
try
{
// define a process to show the file
System.Diagnostics.Process process = new System.Diagnostics.Process();
// declare the path to the file
process.StartInfo.FileName = new Uri(media, UriKind.Absolute).ToString();
process.StartInfo.UseShellExecute = true;
// start the process to show the file to the user
process.Start();
process.WaitForExit();
}
catch
{
MessageBox.Show("Could not open the file.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
要解决这个问题,线程的使用确实很方便。使用线程调用函数使计时器在主线程中继续,而其他事情在另一个线程中并行完成。为实现这一点,这就是我所做的更改。 我更改了 ShowVideo 方法如下:
private void ShowVideo(string media)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = new Uri(media, UriKind.Absolute).ToString();
process.StartInfo.UseShellExecute = true;
Thread showFile = new Thread(() => process.Start());
showFile.Start(); // start the Thread
showFile.Join();
showFile.WaitForExit();
}
catch
{
MessageBox.Show("Could not open the file.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}