将回调Action传递给方法

时间:2014-02-25 19:35:49

标签: c#

这是一个异步方法,可以查询数据库并在某些时候返回。 目前它是这样的:

        this.Model.GetStudentKeys(keysList);
        this.Foo1();
        this.Foo2();

我不熟悉语法,但我需要的是更改上面的代码,以便在完成异步查询后调用这两个Foo方法。所以我知道我需要这样的东西:

 this.Model.GetStudentKeys(keysList, callBack);

Action<object> callback {
   this.Foo1();
   this.Foo2();
}

但就像我说我不熟悉语法一样,你能帮助我吗?

3 个答案:

答案 0 :(得分:4)

您可以使用回调功能,但会被C#的async/await syntax 取代。在我解释所说的语法之前,我将向您展示如何使用Action来实现相同的目标:

/*Action is a reference type, so its assignment is no different. Its value is a lambda
  expression (http://msdn.microsoft.com/en-us/library/bb397687.aspx),
  which you can think of as an anonymous method.*/
private Action<object> callback = o =>
                             {
                                 object result = o;

                                 this.Foo1();
                                 this.Foo2();
                             };

/*It's good practice in C# to append 'Async' to the name of an asynchronous method
  in case a synchronous version is implemented later.*/
this.Model.GetStudentKeysAsync(keysList, callback);

使用这种方法,您的GetStudentsAsync方法必须调用回调,如下所示:

public void GetStudentsAsync(List<string> keys, Action<object> callback)
{
    var returnValue = null;
    //do some stuff...
    callback(returnValue);
} 

您也可以直接将lambda表达式作为参数传递:

this.Model.GetStudentKeysAsync(keysList, o =>
                             {
                                 this.Foo1();
                                 this.Foo2();
                             });

但是,使用.NET 4.5(和使用Microsoft Async package的.NET 4.0),您可以使用C#5提供的asyncawait关键字:

//notice the 'async' keyword and generic 'Task(T)' return type
public async Task<IEnumerable<StudentModel>> GetStudentsAsync(IEnumerable<int> keyList)
{
    /*to invoke async methods, precede its invocation with
      the 'await' keyword. This allows program flow to return
      the line on which the GetStudentsAsync method was called.
      The flow will return to GetStudentsAsync once the database
      operation is complete.*/

    IEnumerable<StudentModel> students = await FakeDatabaseService.ExecuteSomethingAsync();

    return students;
}

只需按以下方式调用上述方法:

IEnumerable<StudentModel> students = await this.Model.GetStudentsAsync(keyList);

答案 1 :(得分:1)

假设GetStudentKeys方法返回Task对象(由于它是异步的),您可以使用(C#5.0中的新建)构造asyncawait

public async void MethodName()
{
    await this.Model.GetStudentKeysAsync(keysList);    // <-- Async operation
    this.Foo1();
    this.Foo2();
}

异步操作完成后,代码将在await关键字后继续。

答案 2 :(得分:1)

你可以像这样定义你的功能

    void GetStudentKeys(keysList, Func<bool> callback)
    {
        Thread th = new Thread(delegate(){
            //do some work in separate thread and inside that thread call
            if(callback != null)
                callback();
        });
        th.Start();
    }

并将函数调用更改为

    this.Model.GetStudentKeys(keysList, () => {
        this.Foo1();
        this.Foo2();
        return true;
    });

类似的东西。