C# Thread.Sleep(ms) 冻结 UI 并且我无法使用替代选项

C# Thread.Sleep(ms) Freezes UI and I can't use Alternative Options

我正在制作包含 CSV 写入的 C# WPF 应用程序。

但是,我想延迟一下。但是当我使用 Thread.Sleep(ms), UI 冻结并且 Windows 表示该程序已停止。

所以,我找到了一些替代方案,例如

private static DateTime Delay(int MS)
     {
         DateTime ThisMoment = DateTime.Now;
         TimeSpan duration = new TimeSpan(0, 0, 0, 0, MS);
         DateTime AfterWards = ThisMoment.Add(duration);
         while (AfterWards >= ThisMoment)
         {
             if (System.Windows.Application.Current != null)
             {
                 System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(delegate { }));
             }
             ThisMoment = DateTime.Now;
         }
         return DateTime.Now;
     }

但是,当我使用这种方法时,程序就停止了。

这是制作、写入 CSV 文件的按钮代码。

 private void button_Click(object sender, RoutedEventArgs e)
    {

        try
        {
            System.IO.StreamWriter file = new System.IO.StreamWriter(@"New.csv");
            int a = 1;
            file.WriteLine("Delta, Theta");
            while (a < 20)
            {

                file.WriteLine("{0}, {1}", TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta);
                a++;
                file.Close();
                Thread.Sleep(3000);    //Delay(3000); When I use Alternative way.
            }
        }
        catch (Exception ex)
        {
            throw new ApplicationException("Broken", ex);
        }
    }

我想知道的主要问题是如何在不冻结的情况下延迟几秒钟UI。抱歉语法错误。

使您的点击处理程序异步。那么就可以使用Task.Delay,不会阻塞线程

private async void button_Click(object sender, RoutedEventArgs e)
{
    try
    {
        System.IO.StreamWriter file = new System.IO.StreamWriter(@"New.csv");
        int a = 1;
        file.WriteLine("Delta, Theta");
        while (a < 20)
        {
            file.WriteLine("{0}, {1}", TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta);
            a++;
            file.Close();
            await Task.Delay(3000);
        }
    }
    catch (Exception ex)
    {
        throw new ApplicationException("Broken", ex);
    }
}

顺便说一句,这里有一种解决异常的方法:

private async void button_Click(object sender, RoutedEventArgs e)
{
    const string fileName = @"New.csv";
    try
    {
        File.AppendAllText(fileName, "Delta, Theta");
        for (var a=1; a<20; a++)
        {
            var text = string.Format("{0}, {1}", TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta);
            File.AppendAllText(fileName, text);
            await Task.Delay(3000);
        }
    }
    catch (Exception ex)
    {
        throw new ApplicationException("Broken", ex);
    }
}
 private async void CSVexport_Click(object sender, RoutedEventArgs e)  //to use Await Task.Delay(ms) Option
    {

        try
        {
            SaveFileDialog saveAsfile = new SaveFileDialog();  //Save As File

            saveAsfile.InitialDirectory = @"C:\";
            saveAsfile.Title = "Save As File";
            saveAsfile.Filter = "CSV Document(*.csv)|*.csv|All Files(*.*)|*.*";
            saveAsfile.DefaultExt = "csv";
            saveAsfile.AddExtension = true;
            if (saveAsfile.ShowDialog() == System.Windows.Forms.DialogResult.OK)  //Save As File Function
            {
                GaugeSignal.Value = 1;
                if (TGLatestData.PoorSignal != -1)
                {
                    var SignalQuality = Math.Round((200D - TGLatestData.PoorSignal) / 2D, 1);
                    if (SignalQuality < 0) SignalQuality = 0;
                    GaugeSignal.Value = SignalQuality;
                    TGLatestData.PoorSignal = TGLatestData.PoorSignal;
                }
                SQZero.Visibility = 0;
                CSVexport.Visibility = Visibility.Hidden;
                FileStream filestream = new FileStream(saveAsfile.FileName, FileMode.Create, FileAccess.Write);
                System.Windows.MessageBox.Show("CSV Writing...\nIf you want to stop Writing CSV, Click SQ to 0 Button,", "CSV Writing...", MessageBoxButton.OK, MessageBoxImage.Warning);
                System.IO.StreamWriter file = new System.IO.StreamWriter(filestream);
                int time = 1000;
                file.WriteLine("Signal Quality, Delta, Theta, Alpha1, Alpha2, Beta1, Beta2, Gamma1, Gamma2, Attention, Meditation, Mental Effort, Task Familiarity, Task Difficulty, Blink Strength");
                while (true)  //infinite loop
                {
                    double Check_Signal_Zero_To_Stop = GaugeSignal.Value;
                    file.WriteLine("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}", GaugeSignal.Value, TGLatestData.EegPowerDelta, TGLatestData.EegPowerTheta, TGLatestData.EegPowerAlpha1, TGLatestData.EegPowerAlpha2, TGLatestData.EegPowerBeta1, TGLatestData.EegPowerBeta2, TGLatestData.EegPowerGamma1, TGLatestData.EegPowerGamma2, TGLatestData.Attention, TGLatestData.Meditation, TGLatestData.MentalEffort, TGLatestData.TaskFamiliarity, TGLatestData.TaskDifficulty, TGLatestData.BlinkStrength);
                    await Task.Delay(time);  //Delay Without FreezingUI (need async)
                    if (Check_Signal_Zero_To_Stop == 0)
                    {
                        file.Close();  //if you click SQ to 0, Do file.Close
                        while (true) await Task.Delay(1000000000); 
                    }
                }
            }
        }
        catch (ApplicationException ex)
        {
            throw new ApplicationException("This Program is Get Broken", ex);
        }
    }

我将 private void 更改为 'private async void' 以使用 Await Task.Delay(ms) 而不是 Thread.Sleep(ms) 并且我还制作了停止按钮以退出无限循环。 这是 SQ 到 0 按钮源。如果单击此按钮,一个变量(GaugeSignal.Value) 将为 0,它将停止写入 CSV 和保存修改后的文件。

 private async void SQzero_Click(object sender, RoutedEventArgs e)
    {
        int EndTime = 4000;
        SQZero.Visibility = Visibility.Hidden;
        System.Windows.MessageBox.Show("Stop Writing CSV... \nWait a Seconds..", "CSV Saving..", MessageBoxButton.OK, MessageBoxImage.Warning);
        GaugeSignal.Value = 0;
        await Task.Delay(EndTime);    //Wait for Delay of CSVexport_btn
        System.Windows.MessageBox.Show("CSV Saved!", "CSV Saved", MessageBoxButton.OK, MessageBoxImage.Warning);
        CSVexport.Visibility = Visibility.Visible;  //to Save another one Again
    }

我是愚蠢的。我在循环中使用了 file.Close(); 。所以,它说 IOException。我找到了其他方法来避免它们并最终得到它。感谢John Wu, Çöđěxěŕ对我的帮助。