【问题标题】:How to use process using Threads without stoping a timer in WPF? [closed]如何在不停止 WPF 中的计时器的情况下使用线程来使用进程? [关闭]
【发布时间】:2022-01-05 20:55:30
【问题描述】:

这是一个小指南,可帮助解决计时器在使用默认应用程序打开文件时停止的问题。

如果您在 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);
    }
}

【问题讨论】:

    标签: wpf multithreading timer process media


    【解决方案1】:

    要解决这个问题,使用线程真的很方便。使用线程调用函数使计时器在主线程中继续,而其他事情在另一个线程中并行完成。为了实现这一点,这就是我所做的改变。 我将 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);
            }
        }
    

    【讨论】:

    • 这没有任何意义。您是否知道您没有在这里调用 WaitForExit ,就像您在问题中的代码中所做的那样?除此之外,完全不清楚实际的“问题”是什么。
    • @Clemens 我添加了一个介绍来描述问题。我想记录这一点,以便如果有人遇到这个问题,它可以帮助他们解决它。
    • 这不会编译:showFile.WaitForExit();。考虑删除这个可怕的帖子。对于在启动进程时遇到问题的任何人来说,这是完全错误的,而且毫无用处。
    • 你可能只是不想在你的原始代码中调用process.WaitForExit();,谁知道呢......只为了启动一个进程而产生一个线程是没有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2021-09-18
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多