繁体   English   中英

按下按钮后的while循环功能并在按下另一个按钮时停止循环C#

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM