C # Thread.Sleep (ms) Замерзает пользовательский интерфейс, и я не могу использовать альтернативные параметры - PullRequest
0 голосов
/ 02 ноября 2019

Я делаю C # WPF приложение, которое содержит CSV Writing.

Но я хочу дать некоторые задержки. Но когда я использую Thread.Sleep(ms), пользовательский интерфейс зависает, и 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);
        }
    }

Главный вопрос, который я хочу знать, это как отложить несколько секунд без заморозки интерфейса. Извините за плохую грамматику.

Ответы [ 2 ]

2 голосов
/ 02 ноября 2019

Сделайте ваш обработчик кликов асинхронным. Тогда вы можете использовать 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);
    }
}
0 голосов
/ 03 ноября 2019
 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), и я также сделал кнопку Stop, чтобы выйти из бесконечного цикла. Вот SQ to 0 Button Source. Если вы нажмете эту кнопку, одна переменная (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. Я нашел другой способ избежать их и, наконец, получил его. Спасибо Джону Ву, Çöđěxěŕ, чтобы помочь мне.

...