Silverlight immediate UI update

Silverlight immediate UI update

Old forum URL: forums.lhotka.net/forums/t/5472.aspx


Ash002 posted on Friday, September 26, 2008

Hi All

Using CslaDataProvider we wish to display the busy status while for Cancel operation in addition to the operations for which it is currently displayed.

Busy is display by CslaDataProvider for Fetch. For Save we display busy as well. Both these operations are async operations talking to the server, so the UI is updated when code returns.

Cancel is not an async operation though. So the UI is not updated unitl the code returns, which is after the cancel has completed, some 18 seconds later.

Can the Cancel() be run in a BackgroundWorker? It appears to work, and work well but just seems too good to be true. Whats the recommened approach?

I have also tried a StoryBoard data bound to a data bound to a property to invoke the property in steps. That approach didn't go, but probably just needs a little more work.

BackgroundWorker code:

      Busy = true;
      
      BackgroundWorker worker = new BackgroundWorker();
      worker.DoWork += (o, e) =>
      {
          Provider.Cancel();
      };
      worker.RunWorkerCompleted += (o, e) =>
      {
        Busy = false;
      };
      worker.RunWorkerAsync();

Busy is a dependency property wrapping the CslaDataProvider.IsBusy.

Thanks

Ash002 replied on Friday, September 26, 2008

I noticed elsewhere that Csla object are not thread safe in .net, so BackgroundWorker looks like its out of the question.

Another approach is to use a StoryBoard to create a loop. The operations happen in the StoryBoard's Completed event. The completed event increments a counter and reinvokes the StoryBoard so the next step can take place:


private void CancelCommandExecute(object parameter)
{
      CancelStory.Begin();
}


    private int _cancelStep = 0 ;
           
    void CancelStory_Completed(object sender, EventArgs e)
    {
      switch (_cancelStep)
      {
        case 1:
          Busy = true;
          break ;
         
        case 2:
          Provider.Cancel();
         
Busy = false;
          return ; // Finished
         
      }
      // set next step and loop into StoryBoard again.
      _cancelStep ++;
      CancelStory.Begin();
    }

Any other ideas?

thanks in advance

sergeyb replied on Friday, September 26, 2008

Another quick and dirty approach:  add another busy animation for cancel.  So, you CancelButton_Click looks like this:

cancelBusyAnimation.IsRunning = true;

provider.Cancel();

cancelBusyAnimation.IsRunning = false;

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Ash002 [mailto:cslanet@lhotka.net]
Sent: Friday, September 26, 2008 8:10 AM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] Silverlight immediate UI update

 

I noticed elsewhere that Csla object are not thread safe in .net, so BackgroundWorker looks like its out of the question.

Another approach is to use a StoryBoard to create a loop. The operations happen in the StoryBoard's Completed event. The completed event increments a counter and reinvokes the StoryBoard so the next step can take place:


private void CancelCommandExecute(object parameter)
{
      CancelStory.Begin();
}


    private int _cancelStep = 0 ;
           
    void CancelStory_Completed(object sender, EventArgs e)
    {
      switch (_cancelStep)
      {
        case 1:
          Busy = true;
          break ;
         
        case 2:
          Provider.Cancel();
          Busy = false;
          return ; // Finished
         
      }
      // set next step and loop into StoryBoard again.
      _cancelStep ++;
      CancelStory.Begin();
    }

Any other ideas?

thanks in advance


sergeyb replied on Friday, September 26, 2008

Hmmm…  I wonder why does cancel take so long?  It is pretty much instantaneous on my machine.  How big is your object graph?  Could you try to see how long it takes in unit testing?  I wonder if re-binding in UI is what is taking so long…

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Ash002 [mailto:cslanet@lhotka.net]
Sent: Friday, September 26, 2008 8:07 AM
To: Sergey Barskiy
Subject: [CSLA .NET] Silverlight immediate UI update

 

Hi All

Using CslaDataProvider we wish to display the busy status while for Cancel operation in addition to the operations for which it is currently displayed.

Busy is display by CslaDataProvider for Fetch. For Save we display busy as well. Both these operations are async operations talking to the server, so the UI is updated when code returns.

Cancel is not an async operation though. So the UI is not updated unitl the code returns, which is after the cancel has completed, some 18 seconds later.

Can the Cancel() be run in a BackgroundWorker? It appears to work, and work well but just seems too good to be true. Whats the recommened approach?

I have also tried a StoryBoard data bound to a data bound to a property to invoke the property in steps. That approach didn't go, but probably just needs a little more work.

BackgroundWorker code:

      Busy = true;
      
      BackgroundWorker worker = new BackgroundWorker();
      worker.DoWork += (o, e) =>
      {
          Provider.Cancel();
      };
      worker.RunWorkerCompleted += (o, e) =>
      {
        Busy = false;
      };
      worker.RunWorkerAsync();

Busy is a dependency property wrapping the CslaDataProvider.IsBusy.

Thanks


Ash002 replied on Sunday, September 28, 2008

It was a pretty big collection, 1400 objects Will check to see what is taking the time. Will try a second Busy animation also. thanks
.

Ash002 replied on Sunday, September 28, 2008

Sergey

 

Fetch takes about 6 seconds, on a deliberately large data set.

 

For cancel however cancelling outside the CslaDataProvider is fine, but using the provider is slow. The time taken is in the first loop in BLB.UndoChanges()

 

Code:

          string s = "";

          s += "Rows=" + (Provider.Data as Users).Count.ToString() + "\r";

          s+= DateTime.Now.ToString() + "\r";

         

          var undoable = Provider.Data as Csla.Core.ISupportUndo;

          Provider.Data = null;

          undoable.CancelEdit();

          undoable.BeginEdit();

          Provider.Data = undoable;

          s+= DateTime.Now.ToString() + "\r";

         

          Provider.Cancel();

          s+= DateTime.Now.ToString() + "\r";

          Busy = false;

 

Times:

 

Cancel

Rows=1384

29/09/2008 10:34:14 AM

29/09/2008 10:34:20 AM

29/09/2008 10:34:48 AM

 

 

Cancel

Rows=1384

29/09/2008 10:36:04 AM

29/09/2008 10:36:10 AM

29/09/2008 10:36:38 AM

 

Cancel

Rows=1384

29/09/2008 10:39:41 AM

29/09/2008 10:39:47 AM

29/09/2008 10:40:17 AM

 

 

 

sergeyb replied on Sunday, September 28, 2008

Just a guess…  I think what is taking a long time is rebinding of UI that provider triggers.  Provider itself is just issuing this.Data.Cancel.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Ashley Dickson [mailto:cslanet@lhotka.net]
Sent: Sunday, September 28, 2008 8:50 PM
To: Sergey Barskiy
Subject: RE: [CSLA .NET] RE: Silverlight immediate UI update

 

Sergey

 

Fetch takes about 6 seconds, on a deliberately large data set.

 

For cancel however cancelling outside the CslaDataProvider is fine, but using the provider is slow. The time taken is in the first loop in BLB.UndoChanges()

 

Code:

          string s = "";

          s += "Rows=" + (Provider.Data as Users).Count.ToString() + "\r";

          s+= DateTime.Now.ToString() + "\r";

         

          var undoable = Provider.Data as Csla.Core.ISupportUndo;

          Provider.Data = null;

          undoable.CancelEdit();

          undoable.BeginEdit();

          Provider.Data = undoable;

          s+= DateTime.Now.ToString() + "\r";

         

          Provider.Cancel();

          s+= DateTime.Now.ToString() + "\r";

          Busy = false;

 

Times:

 

Cancel

Rows=1384

29/09/2008 10:34:14 AM

29/09/2008 10:34:20 AM

29/09/2008 10:34:48 AM

 

 

Cancel

Rows=1384

29/09/2008 10:36:04 AM

29/09/2008 10:36:10 AM

29/09/2008 10:36:38 AM

 

Cancel

Rows=1384

29/09/2008 10:39:41 AM

29/09/2008 10:39:47 AM

29/09/2008 10:40:17 AM

 

 

 



sergeyb replied on Sunday, September 28, 2008

BTW, is this data bound to a grid?

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: Ashley Dickson [mailto:cslanet@lhotka.net]
Sent: Sunday, September 28, 2008 8:50 PM
To: Sergey Barskiy
Subject: RE: [CSLA .NET] RE: Silverlight immediate UI update

 

Sergey

 

Fetch takes about 6 seconds, on a deliberately large data set.

 

For cancel however cancelling outside the CslaDataProvider is fine, but using the provider is slow. The time taken is in the first loop in BLB.UndoChanges()

 

Code:

          string s = "";

          s += "Rows=" + (Provider.Data as Users).Count.ToString() + "\r";

          s+= DateTime.Now.ToString() + "\r";

         

          var undoable = Provider.Data as Csla.Core.ISupportUndo;

          Provider.Data = null;

          undoable.CancelEdit();

          undoable.BeginEdit();

          Provider.Data = undoable;

          s+= DateTime.Now.ToString() + "\r";

         

          Provider.Cancel();

          s+= DateTime.Now.ToString() + "\r";

          Busy = false;

 

Times:

 

Cancel

Rows=1384

29/09/2008 10:34:14 AM

29/09/2008 10:34:20 AM

29/09/2008 10:34:48 AM

 

 

Cancel

Rows=1384

29/09/2008 10:36:04 AM

29/09/2008 10:36:10 AM

29/09/2008 10:36:38 AM

 

Cancel

Rows=1384

29/09/2008 10:39:41 AM

29/09/2008 10:39:47 AM

29/09/2008 10:40:17 AM

 

 

 



Ash002 replied on Sunday, September 28, 2008

Yes it is DataBound to the grid, so I am assumming that’s the problem, hence assigning Provider.Data to null to break the data binding.

 

Removing the data binding on the grid’s ItemsSource:

 

    var u = (Users)Provider.Data;

    if (u != null)      u[0].BusinessTitle = "" ;

    {

      u[0].ApplyEdit() ;

 

      string s = "";

      s+= DateTime.Now.ToString() + "\r";

      Provider.Cancel();

      s+= DateTime.Now.ToString() + "\r";

 

29/09/2008 12:59:12 PM

29/09/2008 12:59:21 PM

 

29/09/2008 1:01:28 PM

29/09/2008 1:01:37 PM

 




Copyright (c) Marimer LLC