C # как вызвать обратный вызов? - PullRequest
3 голосов
/ 27 января 2012

Это часть моего кода. Я хочу передать функцию обратного вызова в 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 ]

2 голосов
/ 27 января 2012

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

Также обратите внимание на следующую статью: Асинхронный вызов синхронных методов

0 голосов
/ 27 января 2012

Не уверен, правильно ли я понимаю, но я думаю, что вы хотите снова включить кнопку butOK после обновления пользовательского интерфейса.Если это так, есть два решения.

1) Вы можете изменить

updateUIDelegate del = new updateUIDelegate(updateUI);

на

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

Я изменяю updateUIDelegate на var здесь, потому чтоопределение updateUI на самом деле не соответствует updateUIDelegate.

2) Refactor callback() соответствует определению AsyncCallback и передает его в качестве параметра BeginInvoke().То есть

BeginInvoke(callback, null);

Это более элегантное или официальное использование BeginInvoke, но может потребоваться больше усилий для рефакторинга кода.

0 голосов
/ 27 января 2012

Вы можете передать делегат функции в качестве параметра. Поэтому добавьте параметр в ваш метод «Test» типа «asyncCallback». Затем в методе '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();
    }
}
...