public CloseTask(CloseCallbackType callback) { _callback = callback; }
/// <summary> /// セッションのクローズ操作をおこなうコルーチンを返却します。<br /> /// <br /> /// コルーチンの完了時にはコールバックが返っていることが保証されます。<br /> /// また、セッションのクローズ操作は必ず成功し、コールバックが返った時点でセッションがクローズド状態であり、そのセッションを利用していたすべての API の実行が完了していることが保証されます。<br /> /// ただし、複数のクローズ操作を同時に実行し、そのコールバックでオープン操作を開始した場合はその限りではありません。<br /> /// <br /> /// セッションに対して複数回のオープン操作をおこなっていた場合であっても、1回のクローズ操作でクローズド状態へ移行します。<br /> /// </summary> /// /// <returns>IEnumerator</returns> /// <param name="callback">コールバックハンドラ</param> public IEnumerator Close(CloseCallbackType callback) { var closeTask = new CloseTask(callback); var isNowClosed = false; using (var scopedLock = new NonreentrantLock.ScopedLock(_lock)) { if (_state == State.Idle) { closeTask.Complete(); } else { _closeTaskList.Add(closeTask); while (true) { if (closeTask.IsCompleted) { break; } IEnumerator current = null; switch (_state) { case State.Opening: _state = State.CancellingOpen; current = CancelOpenImpl(); break; case State.Available: ProjectToken = null; if (_gs2SessionTaskList.Count == 0) { _state = State.Closing; current = CloseImpl(); } else { _state = State.CancellingTasks; foreach (var gs2SessionTask in _gs2SessionTaskList) { gs2SessionTask.Cancel(); } } break; case State.CancellingTasks: if (_gs2SessionTaskList.Count == 0) { _state = State.Closing; current = CloseImpl(); } break; case State.Closed: if (_gs2SessionTaskList.Count == 0) { _state = State.Idle; isNowClosed = true; CompleteCloseTasks(); continue; } break; case State.Idle: case State.CancellingOpen: case State.Closing: break; } using (var unlockScope = new NonreentrantLock.ScopedUnlock(_lock)) { yield return(current); } } } } if (isNowClosed) { OnClose?.Invoke(); } closeTask.InvokeCallback(); }