[英]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.