C#如何触发回调?

时间:2012-01-27 03:55:52

标签: c# delegates callback

这是我的代码段的一部分。 我想将一个回调函数传递给test()。 因此,在调用“del”委托后,callback()可以自动触发吗?

功能:

butOK_Click()  //when click the button, disable it
test()  //a wrapper function calling updateUI function
updateUI() // a long process function
callback() // a callback function enabling the button back

我该怎么做? 感谢

public delegate void updateUIDelegate(bool refresh);
public delegate void asyncCallback();            
//...
void butOK_Click(object sender, EventArgs e) {
    butOK.Enabled = false;
    test();
} 
public void updateUI() {
    // long function....doing 10s
}
public void callback() {
    butOK.Enabled = true;
}
public void test() {
    updateUIDelegate del = new updateUIDelegate(updateUI);
    del.BeginInvoke(null,null);
    //??????????
}

3 个答案:

答案 0 :(得分:2)

Plesse,请尝试以下方法:

void button1_Click(object sender, EventArgs e) {
    button1.Enabled = false;
    BeginAsyncOperation(updateUI);
}
void BeginAsyncOperation(Action operation) {
    operation.BeginInvoke(OnAsyncCallback, null);
}
void OnAsyncCallback(IAsyncResult result) {
    if(result.IsCompleted) {
        if(!InvokeRequired)
            callback();
        else BeginInvoke(new Action(callback));
    }
}
//
public void callback() {
    button1.Enabled = true;
    // something else
}
public void updateUI() {
    // long function....doing 10s
    System.Threading.Thread.Sleep(10000);
}

请同时查看以下文章:Calling Synchronous Methods Asynchronously

答案 1 :(得分:0)

您可以将委托作为参数传递给函数。因此,在'asyncCallback'类型的方法'Test'中添加一个参数。然后在'test'方法中,您可以调用传入的委托方法。

以下是一些示例代码:

class MyClass {

    public delegate void updateUIDelegate(bool refresh);
    public delegate void asyncCallback();            

    private void butOK_Click(object sender, EventArgs e)
    {
        butOK.Enabled = false;
        test(new asyncCallback(callback));
    }

    public void updateUI(bool refresh)
    {
        // long function....doing 10s
    }

    public void callback()
    {
        butOK.Enabled = true;
    }

    public void test(asyncCallback callbackMethod)
    {
        updateUIDelegate del = new updateUIDelegate(updateUI);
        del.BeginInvoke(true, null, null);

        if(callbackMethod != null) callback();
    }
}

答案 2 :(得分:0)

不确定我是否理解正确,但我认为您希望在更新UI后重新启用but按钮。如果是这样,有两种解决方案。

1)您可以修改

updateUIDelegate del = new updateUIDelegate(updateUI);

进入

var del = new Action(() => { updateUI(); callback(); });

我在这里将updateUIDelegate更改为var,因为updateUI的定义实际上与updateUIDelegate不匹配。

2)重构callback()以匹配AsyncCallback的定义,并将其作为BeginInvoke()的参数传递。也就是说,

BeginInvoke(callback, null);

这是BeginInvoke的更优雅或官方用法,但可能需要更多努力来重构代码。