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ěŕ对我的帮助。
我正在制作包含 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ěŕ对我的帮助。