早读课老师安排学生们读课文,突然老师想抽根烟,就跟班长说读完跑去告诉他。
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并没有做实际工作,只是在等待结果。
这种场景挺常见,值得注意。