0

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

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();
    }
}
4

3 回答 3

0

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

  • 在 Form1_Load 上,运行 myMethod(),您可以在其中“做某事”(初始化),然后立即返回。不要在这里屏蔽。
  • 在 KeyDown 事件中,如果按下 E,您可以“执行此操作”。那部分应该很容易。
  • 我对您何时想要“执行该操作”运行(即未按下键)感到有些困惑。你能澄清一下这种情况应该在什么时候发生吗?
于 2012-12-09T11:13:25.490 回答
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(). 我建议您在开始使用多个线程之前查看线程同步。

于 2012-12-09T12:28:05.113 回答
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();
}
于 2012-12-09T13:14:47.027 回答