[英]While Loop Function after a button is pressed and stop looping when another button is pressed C#
在我的 Windorm Form 应用程序中,我有两个按钮,当按下按钮 1 时循环函数将开始工作,并在按下按钮 2 后停止执行。 我怎么能这样做来防止我的 GUI 无响应。 我怎么能插入命令while(button2.clicked != true)
我的按钮 1 代码:
private async void EmoStart_Click_1(object sender, EventArgs e)
{
//var repeat = "true";
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (VoiceStart_Click_2 != "true")
{
var image = pictureBox1.Image;
image = resizeImage(image, new Size(1209, 770));
image.Save(imageFilePath);
if (File.Exists(imageFilePath))
{
var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);
if (Emo[0].FaceAttributes.Emotion.Anger >= 0.5)
{
EmoBox.Text = "Anger, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Contempt >= 0.5)
{
EmoBox.Text = "Contempt, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Disgust >= 0.5)
{
EmoBox.Text = "Disgust, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Fear >= 0.5)
{
EmoBox.Text = "Fear, Bad Driving Condition, Soft Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Happiness >= 0.5)
{
EmoBox.Text = "Happiness, Good Driving Condition";
}
else if (Emo[0].FaceAttributes.Emotion.Neutral >= 0.5)
{
EmoBox.Text = "Neutral, Good Driving Condition";
}
else if (Emo[0].FaceAttributes.Emotion.Sadness >= 0.5)
{
EmoBox.Text = "Sadness, Bad Driving Condition, Rock Music will be played";
}
else if (Emo[0].FaceAttributes.Emotion.Surprise >= 0.5)
{
EmoBox.Text = "Happiness, Bad Driving Condition, Soft Music will be played";
}
else
{
EmoBox.Text = "Stable Condition, Good Driving Condition";
}
}
}
而对于我的 button2 代码:
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
string command = await Voice.RecognizeSpeechAsync();
VoiceBox.Text = command;
}
谢谢!
您必须在单独的线程中运行循环。 例如,您可以异步运行它。 像这样的东西:
// start the loop
private async void button1_Click(object sender, EventArgs e)
{
LoopStopped = false;
await StartLoopAsync();
}
// put yor while loop here
private Task StartLoopAsync()
{
return Task.Run(() =>
{
while (LoopStopped == false)
{
var date = DateTime.Now;
System.Diagnostics.Debug.WriteLine(date);
}
System.Diagnostics.Debug.WriteLine("Thread stopped.");
});
}
// stop the loop
private void button2_Click(object sender, EventArgs e)
{
LoopStopped = true;
}
其中LoopStopped
是全局布尔变量。
您放入EmoStart_Click_1
所有操作都是同步运行的,除了:
FaceEmotion.MakeAnalysisRequest(imageFilePath)
因此界面(UI)被冻结。
像您那样将方法的签名更改为异步是不够的。 您必须告诉编译器应该等待哪些其他部分。 你想要你的整个 while 函数异步!
private async void EmoStart_Click_1(object sender, EventArgs e)
{
EmoStart.Enabled = false; //I assume EmoStart is the name of your button
await Task.Factory.StartNew(Loop);
EmoStart.Enabled = true;
}
private void Loop() //since this method doesn't have async in its signature "var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);" won't compile, so you should change to the synchronous equivalent "var Emo = FaceEmotion.MakeAnalysisRequest(imageFilePath).Result;" --> note that it won't block due to "Task.Factory.StartNew".
{
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (...)
{
// do your stuff
}
然后您可以决定如何取消 while 循环。
选项 1 .:您可以使用全局 bool 变量:
private bool emotionsShouldBeProcessed;
然后在EmoStart_Click_1
中将其设置为 true 并设置为 false ,如下所示:
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
VoiceStart.Enabled = false;
emotionsShouldBeProcessed = false;
// start and await voice stuff
VoiceStart.Enabled = true;
}
选项 2 .:您可以使用 CancellationToken 来跟踪是否需要取消。
CancellationTokenSource cSource;
private async void EmoStart_Click_1(object sender, EventArgs e)
{
EmoStart.Enabled = false;
cSource = new CancellationTokenSource();
await Task.Factory.StartNew(() => Loop(cSource.Token));
EmoStart.Enabled = true;
}
private void Loop(CancellationToken cToken)
{
string imageFilePath = "C:\\Users\\Administrator\\source\\repos\\FaceDetection\\FaceDetection\\test3.jpg";
while (true)
{
if (cToken.IsCancellationRequested)
break;
// otherwise do your stuff
}
// some clean up here if necessary
}
private async void VoiceStart_Click_2(object sender, EventArgs e)
{
VoiceStart.Enabled = false;
cSource.Cancel();
VoiceStart.Enabled = true;
}
每当您想设置EmoBox.Text
时它都会崩溃,因为这只会发生在 UI 线程上。 为避免这种情况,您需要请求 UI 线程中断,直到 Textbox/Label/etc 操作正在进行,如下所示:
this.Invoke((MethodInvoket)delegate
{
EmoBox.Text = "...";
});
我还会检查 Emo 数组是否为空,因为面部和情绪识别并不总是成功! 因此,Emo[0] 可能会导致“索引超出范围”异常。 以下代码确保它不为空:
var Emo = ...;
if (Emo.Length > 0)
{
if (...)
// use Emo[0]
else if (...)
// use Emo[0] differently
}
让我知道是否有任何不清楚的地方。
您可以创建一个 bool 变量并在您的变量为真时进行循环。
因此,当单击 button1 时,将变量设置为 true。
然后你的 while 看起来像这样:
while(myBoolVariable)
当单击 button2 时,您可以将值更改为 false,while 将停止。
您可以使用全局变量(bool 是一个不错的选择)
当 VoiceStart_Click_2 改变变量时
并在单击 EmoStart_Click_1 时检查变量
if (variable==true)
{
var Emo = await FaceEmotion.MakeAnalysisRequest(imageFilePath);
if (Emo[0].FaceAttributes.Emotion.Anger >= 0.5)
{
EmoBox.Text = "Anger, Bad Driving Condition, Soft Music will be played";
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.