title: Multi-threading with WPF ui
body: <p>I'm not sure if this is possible, but I couldn't find anything when I searched about it. </p>
  
  <p>I have a visual schedule made in WPF that loads and displays appointments. The problem is that it takes a while to load all the visuals and the program becomes unresponsive during that time.</p>
  
  <p>Is it possible to load the appointment visuals and modify the schedule grid in a separate thread while leaving the main thread open for other things? Or possibly keep the schedule grid permanently in a second STA thread so it can do its own thing without interfering with the window?</p>
  
  <p>edit:</p>
  
  <p>Currently what I have:</p>
  
  <pre><code>    private static void FillWeek()
      { 
          BindingOperations.EnableCollectionSynchronization(ObservableAppointments, _lockobject);
          for (int i = 1; i &lt; 6; i++)
          {
              FillDay(Date.GetFirstDayOfWeek().AddDays(i).Date);
          }
      }
      private static ObservableCollection&lt;AppointmentUIElement&gt; ObservableAppointments = new ObservableCollection&lt;AppointmentUIElement&gt;();
      private static object _lockobject = new object();
      public static async Task FillDay(DateTime date)
      {
          ClearDay(date);
          Appointment[] Appointments;
          var date2 = date.AddDays(1);
          using (var db = new DataBaseEntities())
          {
              Appointments = (from Appointment a in db.GetDailyAppointments(2, date.Date) select a).ToArray();
          }
          await Task.Run(()=&gt;
          {
              foreach (Appointment a in Appointments)
              {
                  var b = new AppointmentUIElement(a, Grid);
                  ObservableAppointments.Add(b);
              }
          });      
      }
      private static void ObservableAppointments_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
      {
          if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
          {
              var a = e.NewItems[0] as AppointmentUIElement;
              a.Display();
          }
      }
      private static void ClearDay(DateTime date)
      {
          var Queue = new Queue&lt;AppointmentUIElement&gt;(Grid.Children.OfType&lt;AppointmentUIElement&gt;().Where(a =&gt; a.Appointment.Start.DayOfWeek == date.DayOfWeek));
          while (Queue.Count &gt; 0)
          {
              var x = Queue.Dequeue();
              Grid.Children.Remove(x);
              ObservableAppointments.Remove(x);
          }
          var Queue2 = new Queue&lt;GridCell&gt;(Grid.Children.OfType&lt;GridCell&gt;().Where(g =&gt; g.Date.Date == date));
          while (Queue2.Count &gt; 0)
          {
              Queue2.Dequeue().AppointmentUIElements.RemoveAll(a =&gt; true);
          }
      }
  </code></pre>
  
  <p><code>AppointmentUIElement</code> is derived from <code>Border</code></p>