最近,我正在阅读Jon Skeet 博客中的Eduasync 连载。当我阅读第 7 部分时,一个问题阻止了我,我认为 C# 生成的状态机在某些极少数情况下可能无法正常工作,让我们深入代码(此代码来自 Jon Skeet 的 Eduasync 第 7 部分,我只是添加一些赞扬):
public void MoveNext()
{
int result;
try
{ // doFinallyBodies is never used
bool doFinallyBodies = true;
if (state != 1)
{
if (state != -1)
{
task = Task<int>.Factory.StartNew(() => 5);
awaiter = task.GetAwaiter();
// In a rare case, in this moment the task still has not completed,
// so return false IsCompleted
if (awaiter.IsCompleted)
{
goto Label_GetResult;
}
state = 1;
// The task just completed before OnCompleted,
// but in this moment we haven't call the OnCompleted yet,
// so the task's ContinueWith is nothing the task will complete
// without ContinueWith and we will never get back to this StateMachine again.
doFinallyBodies = false;
awaiter.OnCompleted(moveNextDelegate);
}
return;
}
state = 0;
Label_GetResult:
int awaitResult = awaiter.GetResult();
awaiter = new TaskAwaiter<int>();
result = awaitResult;
}
catch (Exception e)
{
state = -1;
builder.SetException(e);
return;
}
state = -1;
builder.SetResult(result);
}
public struct TaskAwaiter<T>
{
private readonly Task<T> task;
internal TaskAwaiter(Task<T> task)
{
this.task = task;
}
public bool IsCompleted { get { return task.IsCompleted; } }
public void OnCompleted(Action action)
{
SynchronizationContext context = SynchronizationContext.Current;
TaskScheduler scheduler = context == null ? TaskScheduler.Current
: TaskScheduler.FromCurrentSynchronizationContext();
task.ContinueWith(ignored => action(), scheduler);
}
public T GetResult()
{
return task.Result;
}
}
那么你认为这可能是一个问题吗?