title: Only a single ContentDialog can be open at any time
body: <p>If I press my login button multiple times, it triggers the message: "An async operation was not properly started. Only a single ContentDialog can be open at any time." (The delay is there to represent the time it takes for the app to contact the server to see if the user is valid.)</p>
  
  <p>If I use MessageDialog everything works ok, but I want to use the extra customisation that ContentDialog provides.</p>
  
  <p><a href="https://stackoverflow.com/questions/33018346/only-a-single-contentdialog-can-be-open-at-any-time-error-while-opening-anoth">This</a> link has not helped. My code example below shows me trying to use it.</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;Page
      x:Class="DuckTracker.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:DuckTracker"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d"&gt;
  
      &lt;Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
              &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
              &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
          &lt;/Grid.RowDefinitions&gt;
  
          &lt;Grid.ColumnDefinitions&gt;
              &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt;
              &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt;
          &lt;/Grid.ColumnDefinitions&gt;
  
          &lt;TextBlock Grid.Row="0" Grid.Column="0" Height="20"&gt;Name:&lt;/TextBlock&gt;
      &lt;TextBox Grid.Row="0" Grid.Column="1" Height="20"&gt;&lt;/TextBox&gt;
      &lt;Button Click="Button_Click" Grid.Row="2" VerticalAlignment="Bottom"&gt;Login&lt;/Button&gt;
      &lt;/Grid&gt;
  &lt;/Page&gt;
  </code></pre>
  
  <p>Code behind:</p>
  
  <pre><code>using System;
  using System.Threading.Tasks;
  using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;
  
  namespace DuckTracker
  {
  
      public sealed partial class MainPage : Page
      {
          public MainPage()
          {
              this.InitializeComponent();
          }
  
          private async void Button_Click(object sender, RoutedEventArgs e)
          {
              bool canLogin = await CanLogin(); 
  
              if (canLogin == false)
              {
                  try
                  {
                       await AlertWithMessages("Fail", "Could not log in!", "ok");
  
                  }
                  catch (Exception ex)
                  {
  
                      var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "Error");
                      await dialog.ShowAsync();
                  }
  
              }
          }
  
          public async Task AlertWithMessages(string title, string msg, string confirm)
          {
              ContentDialog dialog = new ContentDialog()
              {
                  Title = title,
                  Content = msg,
                  PrimaryButtonText = confirm
              };
  
              await ContentDialogMaker.CreateContentDialogAsync(dialog, true);
  
          }
  
          public async Task&lt;bool&gt; CanLogin()
          {
              await Task.Delay(1000);
  
              return false;
          }
      }
  }
  </code></pre>
  
  <p>Code borrowed from link mentioned above:</p>
  
  <pre><code>using System;
  using System.Threading.Tasks;
  using Windows.UI.Xaml.Controls;
  
  namespace DuckTracker
  {
      public static class ContentDialogMaker
      {
          public static async void CreateContentDialog(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }
          public static async Task CreateContentDialogAsync(ContentDialog Dialog, bool awaitPreviousDialog) { await CreateDialog(Dialog, awaitPreviousDialog); }
  
          static async Task CreateDialog(ContentDialog Dialog, bool awaitPreviousDialog)
          {
              if (ActiveDialog != null)
              {
                  if (awaitPreviousDialog)
                  {
                      await DialogAwaiter.Task;
                      DialogAwaiter = new TaskCompletionSource&lt;bool&gt;();
                  }
                  else ActiveDialog.Hide();
              }
              ActiveDialog = Dialog;
              ActiveDialog.Closed += ActiveDialog_Closed;
              await ActiveDialog.ShowAsync();
              ActiveDialog.Closed -= ActiveDialog_Closed;
          }
  
          public static ContentDialog ActiveDialog;
          static TaskCompletionSource&lt;bool&gt; DialogAwaiter = new TaskCompletionSource&lt;bool&gt;();
          private static void ActiveDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args) { DialogAwaiter.SetResult(true); }
      }
  }
  </code></pre>
  
  <p>I added DoingStuff to Button_Click(), which prevents the error message, but I think there must be a better way:</p>
  
  <pre><code>private async void Button_Click(object sender, RoutedEventArgs e)
  {
      if (DoingStuff == false)
      {
          DoingStuff = true;
  
          bool canLogin = await CanLogin();
  
          if (canLogin == false)
          {
              try
              {
  
                  await AlertWithMessages("Fail", "Could not log in!", "ok");
  
              }
              catch (Exception ex)
              {
  
                  var dialog = new Windows.UI.Popups.MessageDialog(ex.Message, "Error");
                  await dialog.ShowAsync();
              }
  
          }
  
          DoingStuff = false;
      }
  }
  </code></pre>