최근에 Jon Skeet’s blog에서 Eduasync serial을 읽었습니다. part 7을 읽었을 때 한 가지 질문으로 인해 C#이 statemachine을 생성하는 것이 드문 경우에 제대로 작동하지 않을 것이라고 생각했습니다. 코드가 깊습니다 (이 코드는 Jon Skeet의 Eduasync 파트 7에서 나온 것입니다).비동기 생성 된 StateMachine에서 MoveNext에 대해 원자 적으로 의미가 있습니까?
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;
}
}
이게 문제가 될 수 있다고 생각하십니까? 내가 제대로 이해를 확인하기 위해
예, 정확하게 묻고 싶습니다. 답장을 보내 주셔서 감사합니다. 그런데 MSDN 문서를 제외하고 ContinueWith()가 "immediatelly"로 예약 될 것입니다. – ivenxu
그건 단지'Task'가 현재'TaskScheduler'에 추가된다는 것을 의미합니다. 그런 다음 스케줄러가 실행됩니다. 네가 물어 본거야? – svick