代码之家  ›  专栏  ›  技术社区  ›  FosterZ

需要C语言的代码解释#

c#
  •  1
  • FosterZ  · 技术社区  · 14 年前

    我需要一行一行地详细解释下面的代码以及流程的运行方式,例如,在调试时。我刚刚在程序中使用了这段代码来避免 cross thread access error . 代码运行良好,但这段代码是关于什么的?

    delegate void updateTextField(string Text);
    private void updateText(string Text)
    {
        if (txtDelegate.InvokeRequired)
        {
            updateTextField del = new updateTextField(updateText);
            txtDelegate.Invoke(del, new object[] { Text });
        }
        else
        {
            txtDelegate.Text = Text;
        }
    }
    

    此方法在 backgroundWorker_DoWork()

    updateText("using delegate");
    

    我还需要给代表们一个解释。我读到过,但我的理解是委托就像指向函数的指针,但是我需要一个简单的例子来清楚的解释。把我当成新手。

    5 回复  |  直到 12 年前
        1
  •  13
  •   jgauffin    14 年前
    // Declaring a delegate function kind of lifts the function away from the 
    // current object and the current thread, making it 'thread-safe' to call 
    // (although it may still not be thread-safe to execute).
    delegate void updateTextField(string Text); 
    private void updateText(string Text)
    {
        // This asks the control if it's running on the same thread as this method is 
        // currently executing, i.e. can I update you directly or do I need to use 
        // the cross thread calling method "Invoke".
        if (txtDelegate.InvokeRequired) 
        {
            // Here we define the delegate function that's going to be Invoked. 
            // Here it's the same function were currently within but when it's invoked 
            // by the following line, it'll be done on the same thread as the control. 
            // At that point, InvokeRequired will return false and the other branch 
            // will be followed to update the actual text on the control.
            updateTextField del = new updateTextField(updateText);             
    
            // Here we invoke the function passing in the Text we want to update the
            // control with as a parameter.
            txtDelegate.Invoke(del, new object[] { Text });         
        }
        else
        {
            // When this function is Invoked, this is the branch that will be followed 
            // (as we're on the same thread as the control) and the text on the control
            //  will be replaced with the text passed in from the Invoke.
            txtDelegate.Text = Text;          
        }
    }
    

    我希望这能更详细地介绍一下,委托“线程安全”的实际机制超出了这个答案的范围。

        2
  •  3
  •   kyndigs    14 年前
    delegate void updateTextField(string Text); // delegate allows updatetext to be passed as a parameter
    private void updateText(string Text) 
    { 
        if (txtDelegate.InvokeRequired) // on a different thread so requires invoke
        { 
            updateTextField del = new updateTextField(updateText); 
            txtDelegate.Invoke(del, new object[] { Text }); // invoke/execute the delegate on the thread
        } 
        else 
        { 
            txtDelegate.Text = Text; 
        } 
    } 
    

    添加到代码中的注释

        3
  •  3
  •   Peter Mortensen sifr_dot_in    12 年前

    updateText 从错误的线程调用(假设 txtDelegate 是一个控件,从创建它的线程(UI线程)以外的任何线程调用,流程如下。

    updateText(String) called on 'wrong' thread
        txtDelegate.InvokeRequired is true
            wrap updateText(String) in a delegate (updateTextField)
            invoke the delegate on the correct thread (passing Text as parameter)
    updateText(String) called on correct thread
        txtDelegate.InvokeRequire is false
            set txtDelegate.Text to Text
    

    updateText(String) called on correct thread
        txtDelegate.InvokeRequire = false
            set txtDelegate.Text to Text
    
        4
  •  3
  •   Peter Mortensen sifr_dot_in    12 年前

    当你说委托就像一个指向方法的指针时,你就明白了。它允许您以安全的方式指定一个方法“Foo”,作为另一个方法“Bar”的参数,“Bar”方法可能在某个阶段调用“Foo”。

    Windows Forms ,应用程序中可能有多个线程,但只允许UI线程对控件进行更改。所以,在 txtDelegate.InvokeRequired 第行,检查线程是否为UI线程。如果是,那么只需将txtDelegate的值设置为normal(在 else 如果不是的话,就变得有点棘手。然后您需要告诉UI线程运行一些代码来更新文本框的值,因为当前线程不能这样做。

    • 委托是包含执行此操作的指令的代码,
    • 用户界面线程就是这样做的,

    读一读 Control.InvokeRequired Property

        5
  •  2
  •   Peter Mortensen sifr_dot_in    12 年前

    委托就像指向函数的指针(我希望您知道C中的函数指针)。因此委托应该与函数具有相同的签名,以便您可以指向它。

    txtDelegate.InvokeRequired请求

    否则,我们可以进行正常的更改(同一线程)。