等待用户的回应

时间:2012-12-09 10:49:22

标签: c#

当加载表单时myMethod()被调用,然后它执行一些语句。在某些时候,当它到达if语句时它应该停止并等待用户按下某个按钮然后它将根据用户的操作继续执行。我使用了Thread.Sleep()和ManualResetEvent obj的WaitOne()方法,但它们似乎冻结了整个过程,直到时间到期才能做任何事情。我认为KeyEventHandler应该在后台运行,所以它永远不会过时......无论如何我怎么能这样做?

public partial class Form1 : Form
{
    bool pressed = false;
    public Form1()
    {
        InitializeComponent();
        this.KeyPreview = true;
        this.KeyDown +=new KeyEventHandler(Form1_KeyDown);
    }

    void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.E)
        {
            pressed = true;
        }
    }

    void myMethod()
    { 
        while (someBool)
        {
            //do something
            if (pressed)
            //do this
            else 
            //do that
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        myMethod();
    }
}

3 个答案:

答案 0 :(得分:0)

攻击此问题的方式并不是很好,因为在等待用户输入时不应该阻止GUI线程。你应该做任何你能做的事情,然后立即返回,以便GUI线程可以处理消息。

  • 在Form1_Load上,运行myMethod(),您可以在其中“执行某些操作”(初始化),然后立即返回。不要在这里阻止。
  • 在KeyDown事件中,如果按下E,则可以“执行此操作”。那部分应该很容易。
  • 我有点困惑你什么时候想要“做那个”运行(即没有按下键)。你能澄清这种情况何时发生?

答案 1 :(得分:0)

尝试以Task

开始您的方法
private void Form1_Load(object sender, EventArgs e)
{
    System.Threading.Tasks.Task t = new Task(() => myMethod());
    t.Start();
}

在方法中测试pressed时,请将其设置为false

void myMethod()
{ 
    while (someBool)
    {
        //do something
        if (pressed)
        {
            pressed = false;
            //do this
        }
        else 
        //do that
    }
}

当然,这可能会导致各种多线程错误,具体取决于您在myMethod()中的实际操作。我建议您在开始使用多个线程之前先查看thread synchronization

答案 2 :(得分:0)

将定时器组件添加到表单并将其间隔设置为您要等待用户输入的持续时间(以毫秒为单位):

bool someBool = true;

public Form1()
{
    InitializeComponent();
    KeyPreview = true;
    timer1.Interval = 1000;
}

在表单加载时启动计时器:

private void Form1_Load(object sender, EventArgs e)
{
    timer1.Start();
}

添加计时器Tick事件处理程序。如果用户在指定的等待超时(timer1.Interval)期间未按任何键,则会引发此事件。此事件也会定期引发而不是你的while循环:

private void timer1_Tick(object sender, EventArgs e)
{
    if (someBool)    
        //do that
    else
        timer1.Stop();       
}

在KeyDown事件处理程序停止计时器上,然后处理按下的键,并启动计时器以等待下一个用户输入(如果没有输入,则为do that):

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    timer1.Stop();
    if (!someBool)
        return;

    if (e.KeyCode == Keys.E)
        // do this
    else
        // do that

    timer1.Start();
}