/// <summary> /// Opens new <see cref="Session"/> with specified <see cref="SessionConfiguration"/> asynchronously. /// </summary> /// <param name="configuration">The session configuration.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous operation.</returns> /// <sample><code> /// var ctSource = new CancellationTokenSource(); /// using (var session = await domain.OpenSessionAsync(configuration, ctSource.Token)) { /// // work with persistent objects here /// } /// </code></sample> /// <seealso cref="Session"/> public Task <Session> OpenSessionAsync(SessionConfiguration configuration, CancellationToken cancellationToken = default) { ArgumentValidator.EnsureArgumentNotNull(configuration, nameof(configuration)); SessionScope sessionScope = null; try { if (configuration.Supports(SessionOptions.AutoActivation)) { sessionScope = new SessionScope(); } return(OpenSessionInternalAsync(configuration, null, sessionScope, cancellationToken)); } catch { sessionScope?.Dispose(); throw; } }
internal async Task <Session> OpenSessionInternalAsync(SessionConfiguration configuration, StorageNode storageNode, SessionScope sessionScope, CancellationToken cancellationToken) { ArgumentValidator.EnsureArgumentNotNull(configuration, nameof(configuration)); configuration.Lock(true); if (isDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogOpeningSessionX, configuration); } Session session; if (SingleConnection != null) { // Ensure that we check shared connection availability // and acquire connection atomically. lock (singleConnectionGuard) { if (singleConnectionOwner != null) { throw new InvalidOperationException(string.Format( Strings.ExSessionXStillUsesSingleAvailableConnection, singleConnectionOwner)); } session = new Session(this, storageNode, configuration, false); singleConnectionOwner = session; } } else { // DO NOT make session active right from constructor. // That would make session accessible for user before // connection become opened. session = new Session(this, storageNode, configuration, false); try { await((SqlSessionHandler)session.Handler).OpenConnectionAsync(cancellationToken) .ContinueWith(t => { if (sessionScope != null) { session.AttachToScope(sessionScope); } }, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously) .ConfigureAwait(false); } catch (OperationCanceledException) { await session.DisposeSafelyAsync().ConfigureAwait(false); throw; } } NotifySessionOpen(session); return(session); }