为什么我的代码设置标签文本有时不能被正确调用?

时间:2009-06-09 18:27:39

标签: c# .net winforms

我在应用程序的WinForm中有一个标签,我为它创建了一个帖子 设置标签的Text属性。 因为代码负责设置的Text属性 标签是另一个线程,我这样写了:

private void SetLabel8Text(string text)
    {
        try
        {
            if (this.label8.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetLabel8Text);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.label8.Text = text;
            }
        }
        catch (Exception ex)
        {

        }

    }

现在,我也像这样处理KeyPress事件:

    if (e.KeyChar.ToString() == "\r")
            {
        SetLabel8Text("Enter key Pressed !");
    }

我面临的问题是按下Enter键后(执行 KeyPress事件),SetLabel8Text方法永远不会被执行。

其他一切似乎都很顺利, 我试着单步执行代码,它挂在这个地方(在SetLabe8Text方法内部:

this.Invoke(d,new object [] {text});

它挂起并且不会前进一点。

6 个答案:

答案 0 :(得分:4)

好吧,你吞下SetLabel8Text抛出的任何异常都会让人很难确切地知道发生了什么。你应该永远无条件地吞下异常而不至少记录正在发生的事情。 (你也不应该只捕获“异常”。捕获更具体的异常类型)。你能发一个简短但完整的程序来证明这个问题。

在按键事件和SetLabel8Text中添加记录也会有所帮助。

答案 1 :(得分:1)

尝试拨打BeginInvoke而不是Invoke

Invoke是一个阻止通话,因此您可能会遇到竞争条件。 (Invoke在方法实际执行之前不会返回,但只有在UI线程处理其消息循环后才能执行该方法。

答案 2 :(得分:0)

尝试以下方法:

if(e.KeyChar == '\n')
    SetLabel8Text("Enter key Pressed !");

答案 3 :(得分:0)

尝试:

if (e.KeyCode == Keys.Enter) {
}

答案 4 :(得分:0)

一个可能的解释可能是你接下来要做的事情。假设在另一个线程中调用了SetLabel8Text函数,它将需要调用,从而再次执行。但是,它第二次执行(因此不需要调用)它在拥有GUI的线程中执行,通常是主线程。因此,如果你的应用程序中的其他地方有一段时间阻塞主线程的代码,那么看起来SetLabel8Text函数永远不会被执行第二次。为了简单起见,总是将繁重的任务线程化并保持主线程空闲。

答案 5 :(得分:0)

您没有遵循winforms的基本原则:仅在UI线程上创建UI控件。您的KeyPress事件的事件处理程序位于UI线程上,因此,如果您的标签是在UI线程上创建的,则不需要在其上使用BeginInvoke / Invoke。

如果你在UI线程以外的线程中创建表单,控件等,你可能做错了。

请参阅:http://weblogs.asp.net/justin_rogers/pages/126345.aspx了解血腥细节。