C#异步等待按钮单击

时间:2018-10-08 16:09:10

标签: c# button foreach async-await

我是C#异步等待机制的新手。我已经检查了异步的所有先前示例,等待,但是没有一个与我的完全一样。我想做什么?我有一个foreach循环,我想按一定的规则停止它,做一些事情,然后单击按钮继续运行。 这是简单的代码示例:

private void RunConvert()  // START 
{
    foreach (PartSettings File in PartsFromXLS)  // RUNING THE FOREACH LOOP ON A LIST
    {
        ProcessSinglePart(PathStep, PathMCX);
    }
}

public static async void ProcessSinglePart(string PartPathToRead, string PartPathToSave)
{
    // DO SOME STUFF BEFORE THE CHECK

    if (PartLength < PartWidth) // SOME CHECK VALUES
    {
         await WhenClicked();  //HERE I WOULD LIKE TO WAIT FOR BUTTON CLICK
    }

    //DO SOME STUFF AFTER THE CHECK
}

private void GeometryOK_Click(object sender, EventArgs e) 
{
    //  I WOULD LIKE TO WAIT FOR THIS CLICK
}

1 个答案:

答案 0 :(得分:5)

await暂停方法的执行,直到参数(实际上必须为TaskTask之类的参数(必须为Task<T>)为止。您的问题实际上是我遇到过多次的问题:

  

如何异步等待某些事件被触发

在您的情况下,“某些事件”是单击按钮。幸运的是,TaskCompletionSource<T>(以下称为TCS)非常适合解决此问题。首先在课程级别声明一个TCS:

private TaskCompletionSource<bool> clickWaitTask;

没有TCS的非通用版本,所以我通常只使用bool。在这种情况下,我们实际上并不关心数据。然后您的方法如下所示(说明如下):

public static async void ProcessSinglePart(string PartPathToRead, string PartPathToSave)
{
    // DO SOME STUFF BEFORE THE CHECK
    clickWaitTask = new TaskCompletionSource<bool>();

    if (PartLength < PartWidth) // SOME CHECK VALUES
    {
         await clickWaitTask.Task;
    }

    //DO SOME STUFF AFTER THE CHECK
}

您创建一个新的TCS,以便每次运行此逻辑时,它将等待单击发生。然后,您等待Task属性(实际上是Task<T>)。仅当在TCS对象上调用TrySetResult时,该任务才能完成。在按钮单击处理程序(或WPF的命令处理程序)中执行以下操作:

 clickWaitTask.TrySetResult(true); //Value does not matter

正如评论者所指出的那样,除非您处于事件处理程序中,否则不应该使用async void,并且在这种情况下,应在方法周围使用try/catch以避免未处理的异常带来麻烦。我也非常警惕您的public static,但这是一个单独的问题。