예제 #1
0
        /// <summary>
        /// This will "seems" that is working, but taking deeper look, we can see that actually an error was thrown (use the debugger).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MakeTeaAsyncUsingTPLNoDispatcher_OnClick(object sender, RoutedEventArgs e)
        {
            BeforeMakingTea();
            Task.Run(async() =>
            {
                _finalMessage = new StringBuilder();
                _finalMessage.AppendLine("Making tea started.");

                _finalMessage.AppendLine(await MakeTeaAsync.MakeMeTeaAsync());
                Notes.Text = _finalMessage.ToString();
            });
            AfterMakingTea();
        }
예제 #2
0
        /// <summary>
        /// Will make the tea in a async way.
        /// The UI thread is available again and we can perform any actions while the code is been executed somewhere else.
        /// This will introduce a state machine and a continuation.
        /// Once the job is done, the UI thread will update the finalMessasge text
        /// And carry on with the following piece of code.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MakeTeaAsynchronous_OnClick(object sender, RoutedEventArgs e)
        {
            // UI Thread
            BeforeMakingTea();
            _finalMessage = new StringBuilder();
            _finalMessage.AppendLine("Making tea started.");

            // Will spin a new thread and the UI thread is released from the work.
            _finalMessage.AppendLine(await MakeTeaAsync.MakeMeTeaAsync());

            Notes.Text = _finalMessage.ToString();

            AfterMakingTea();
        }
예제 #3
0
        /// <summary>
        /// This will crash the application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MakeTeaAsynchronousConfigureAwaitFalse_OnClick(object sender, RoutedEventArgs e)
        {
            BeforeMakingTea();

            _finalMessage = new StringBuilder();
            _finalMessage.AppendLine("Making tea started.");

            // Adding ConfigureAwait false, will indicate that we don't care that the continuation been executed in a different thread.
            // Because this is a UI component, we can see that we are trying to update the UI with something, and because we are
            // in a different thread in the continuation, the application will crash.
            _finalMessage.AppendLine(await MakeTeaAsync.MakeMeTeaAsync().ConfigureAwait(false));

            Notes.Text = _finalMessage.ToString();
            AfterMakingTea();
        }
예제 #4
0
        /// <summary>
        /// This scenario will cause a Deadlock. See GiveMeStringFromAnInt() for a more info.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MakeTeaAsyncDeadlock_OnClick(object sender, RoutedEventArgs e)
        {
            BeforeMakingTea();
            try
            {
                _finalMessage = new StringBuilder();
                _finalMessage.AppendLine("Making tea started.");
                MakeTeaAsync.MakeMeTeaAsync().Wait();

                // Now comment the above Wait() and try the below line instead.
                // var result = MakeTeaAsync.MakeMeTeaAsync().Result;
                _finalMessage.AppendLine("After calling the method async");

                Notes.Text = _finalMessage.ToString();
            }
            catch (Exception exception)
            {
                Notes.Text = exception.Message;
            }
            AfterMakingTea();
        }
예제 #5
0
        /// <summary>
        /// This example will achieve the same as above but without adding any async and await keyword.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MakeTeaAsyncUsingTPLDispatcherContinuation_OnClick(object sender, RoutedEventArgs e)
        {
            BeforeMakingTea();
            var makeTeaTask = Task.Run(async() =>
            {
                _finalMessage = new StringBuilder();
                _finalMessage.AppendLine("Making tea started.");

                _finalMessage.AppendLine(await MakeTeaAsync.MakeMeTeaAsync());

                Dispatcher.Invoke(() =>
                {
                    Notes.Text = _finalMessage.ToString();
                });
            });

            makeTeaTask.ContinueWith(_ =>
            {
                Dispatcher.Invoke(AfterMakingTea);
            });
        }
예제 #6
0
        private void MakeTeaAsyncUsingTPLCancellationSecondAttempt_OnClick(object sender, RoutedEventArgs e)
        {
            if (cancellationTokenSource != null)
            {
                // Already have an instance of the cancellation token source?
                // This means the button has already been pressed!

                cancellationTokenSource.Cancel();
                cancellationTokenSource = null;

                TplCancellationSecondButton.Content = "TPL - Cancellation 2";
                return;
            }

            cancellationTokenSource = new CancellationTokenSource();

            TplCancellationSecondButton.Content = "Cancel";

            BeforeMakingTea();
            var makeTeaTask = Task.Run(async() =>
            {
                _finalMessage = new StringBuilder();
                _finalMessage.AppendLine("Making tea started.");

                _finalMessage.AppendLine(await MakeTeaAsync.MakeMeTeaAsync());

                Dispatcher.Invoke(() =>
                {
                    Notes.Text = _finalMessage.ToString();
                });
            }, cancellationTokenSource.Token);

            makeTeaTask.ContinueWith(_ =>
            {
                Dispatcher.Invoke(AfterMakingTea);
                cancellationTokenSource             = null;
                TplCancellationSecondButton.Content = "TPL - Cancellation 2";
            });
        }