Example #1
0
		/// <summary>
		///     Loads the specified session.
		/// </summary>
		/// <param name="session">The session to load.</param>
		/// <returns>
		///     <see cref="System.Threading.Tasks.Task{T}" /> that can be awaited.
		/// </returns>
		/// <exception cref="ArgumentNullException">
		///     If <paramref name="session" /> is null.
		/// </exception>
		/// <exception cref="ArgumentException">
		///     If <paramref name="session" /> has been already loaded or canceled.
		/// </exception>
		public async Task<Session> Load( Session session )
		{
			//Contract.Requires<ArgumentNullException>( session != null, "session" );

			if( session.State != SessionState.Created )
			{
				throw new ArgumentException( "Invalid session state.", "session" );
			}

			ActionRegistration action;

			if( !_actions.TryGetValue( session.Action, out action ) )
			{
				throw new Exception( "Session with invalid action." );
			}

			if( !action.Validate( session ) )
			{
				session.State = SessionState.Complete;

				return session;
			}

			lock( _sessions )
			{
				if( session.Exclusive )
				{
					if( _sessions.Count > 0 )
					{
						foreach( var existingSession in _sessions )
						{
							existingSession.Cancel();
						}

						_sessions.Clear();
					}
				}

				_sessions.Add( session );
			}

			OnSessionStarted( new SessionEventArgs( session ) );

			if( session.IsCancellationRequested )
			{
				lock( _sessions )
				{
					_sessions.Remove( session );
				}

				return session;
			}

			session.State = SessionState.Active;

			if( DataExchangeService != null )
			{
				DataExchangeService.BeginDataExchange();
			}

			Task task = null;

			try
			{
				task = action.Process( session );
			}
			catch( Exception ex )
			{
				lock( _sessions )
				{
					_sessions.Remove( session );
				}

				if( DataExchangeService != null )
				{
					DataExchangeService.EndDataExchange();
				}

				var canceled = ex is OperationCanceledException;
				var eventArgs = new SessionAbortedEventArgs( session, canceled ? null : ex );

				OnSessionAborted( eventArgs );

				if( !canceled && !eventArgs.Handled )
				{
					if( ViewModelExceptionHandlingService == null || !ViewModelExceptionHandlingService.HandleException( this, session, ex ) )
					{
						throw;
					}
				}

				return session;
			}

			if( task == null )
			{
				lock( _sessions )
				{
					_sessions.Remove( session );
				}

				session.State = SessionState.Complete;

				if( DataExchangeService != null )
				{
					DataExchangeService.EndDataExchange();
				}

				OnSessionComplete( new SessionEventArgs( session ) );

				return session;
			}

			try
			{
				await task;

				session.State = SessionState.Complete;

				OnSessionComplete( new SessionEventArgs( session ) );
			}
			catch( Exception ex )
			{
				var canceled = ex is OperationCanceledException;
				var eventArgs = new SessionAbortedEventArgs( session, canceled ? null : ex );
				var aggregateException = ex as AggregateException;

				if( aggregateException != null )
				{
					canceled = aggregateException.InnerExceptions.OfType<OperationCanceledException>().Any();
				}

				OnSessionAborted( eventArgs );

				if( !canceled && !eventArgs.Handled )
				{
					if( ViewModelExceptionHandlingService == null || !ViewModelExceptionHandlingService.HandleException( this, session, ex ) )
					{
						throw;
					}
				}
			}
			finally
			{
				lock( _sessions )
				{
					_sessions.Remove( session );
				}

				if( DataExchangeService != null )
				{
					DataExchangeService.EndDataExchange();
				}
			}

			return session;
		}
Example #2
0
		/// <summary>
		///     Raises the session aborted event.
		/// </summary>
		/// <param name="e">
		///     The <see cref="Digillect.Mvvm.SessionAbortedEventArgs" /> instance containing the event data.
		/// </param>
		protected virtual void OnSessionAborted( SessionAbortedEventArgs e )
		{
			if( SessionAborted != null )
			{
				SessionAborted( this, e );
			}
		}