{C#} 如何将事件回调包装成任务

早读课老师安排学生们读课文,突然老师想抽根烟,就跟班长说读完跑去告诉他。

public class ReadEventArgs : EventArgs
{
    public object State { get; set; }

    public int Length { get; set; }

    public List<ArraySegment<byte>> Content { get; set; }

    public event EventHandler<ReadEventArgs> Finished;
}

public class Student
{
    public void ReadAsync(ReadEventArgs eventArgs)
    {
        // 这个方法会很快返回。但是,在学生读书结束的时候,Finished事件会自动触发。
    }
}

public class Monitor
{
    private Student _student = new Student();
    public Task<bool> WatchStudentRead()
    {

    }
}

class Teacher
{
    Monitor _monitor = new Monitor();

    public async void Smoke()
    {
        var task = _monitor.WatchStudentRead();

        // smoking

        await task;

        // go back to classroom
    }
}

请问这里班长怎么做,才能实现异步任务? Student.ReadAsync实际上不是异步方法,不可以await,也不代表完成,这意味着 WatchStudentRead 内部创建task也是行不通的。

好在TPL神通广大,我们可以通过TaskCompletionSource来实现。 TaskCompletionSource可以只管理任务,但不运行实际任务。

    Monitor.cs
    public Task<bool> WatchStudentRead()
    {
        var tasksource = new TaskCompletionSource<bool>();

        var e = new ReadEventArgs();
        e.State = tasksource;
        e.Finished += OnReadFinished;

        _student.ReadAsync(e);

        return tasksource.Task;
    }

    private void OnReadFinished(object sender, ReadEventArgs e)
    {
        var tasksource = e.State as TaskCompletionSource<bool>;

        if (tasksource != null)
        {
            tasksource.SetResult(e.Length > 0);
        }
    }

怎么样,是不是很有趣,返回的task并没有做实际工作,只是在等待结果。
这种场景挺常见,值得注意。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容