美文网首页
{C#} 如何将事件回调包装成任务

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

作者: windflow | 来源:发表于2016-10-28 17:10 被阅读0次

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

    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并没有做实际工作,只是在等待结果。
    这种场景挺常见,值得注意。

    相关文章

      网友评论

          本文标题:{C#} 如何将事件回调包装成任务

          本文链接:https://www.haomeiwen.com/subject/ymseuttx.html