1

我有一个带有取消按钮的模式对话框,仅当用户单击按钮时才会弹出。弹出模态对话框后,我想开始一个监视外部事件的长过程。如果事件发生,则对话框将自动关闭。用户可以通过单击取消按钮来取消监控过程。

我将流程开始分配给 Shown 事件

private void ProceedForm_Shown(object sender, System.EventArgs e)
{
    controller.StartSwiping();
}

过程本身就是一个循环

public void StartSwiping()
{           
    Status status;
    do
    {
        status = CallForFeedback();
    } while (status == Status.Pending);           

    form.DialogResult = DialogResult.OK;
    form.Close();
}

该过程开始正常,但没有弹出对话框,因此用户不能取消该过程。我还尝试将开始分配给 Load 事件,但没有任何改变。有什么方法可以显示对话框,然后开始该过程?

谢谢

4

4 回答 4

4

您的问题是您正在 UI 线程中执行所有操作。您需要将状态监控循环放在一个单独的线程中,以便 UI 线程可以保持响应。

有几种方法可以做到这一点,但一个简单的起点是使用BackgroundWorker 类

于 2012-07-25T14:50:55.233 回答
1

使用 aTask来做你的LongRunning事件:

CancellationTokenSource _cancelationTokenSource = new CancellationTokenSource();
new Task(() => 
{ 
  //Do LongRunning task
}, _cancelationTokenSource.Token, TaskCreationOptions.LongRunning).Start();

需要时使用_cancelationTokenSource取消任务。

于 2012-07-25T14:53:03.567 回答
1

其他人建议使用 BackgroundWorker 或其他类型的后台线程。虽然在许多情况下这在这里是合适的,但可能有更好的解决方案。你不只是在做一些长期运行的任务,你在等待某事发生。而不是不断地轮询......不管它是什么,你应该使用事件。完成后应该会触发一个事件,并且当满足正确条件时,您应该订阅该事件以执行您需要执行的任何操作(即关闭对话框)。

于 2012-07-25T15:03:14.717 回答
1

当您阻塞 UI 线程时,我会将长时间运行的代码移动到后台线程,这就是 UI 从不显示的原因。

为控制器功能使用后台工作者类http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

当后台工作人员完成工作(即收到事件)时,您可以使用以下机制回调到 UI 线程:

http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

注意:文章说您可以关闭 crossthreadexception 这将被认为是不好的做法,而是使用 InvokeRequired 检查以正确的方式处理它,然后在 windows 窗体上调用方法。

于 2012-07-25T14:54:42.283 回答