0

While developing a WPF application with a WCF service I realized that sometimes the application is really slow. For example, when I call a method from the WCF service which returns a list, it takes too much time to execute this. Here is some code:

MVVM:

private ObservableCollection<tblStock> _Stocks;
public ObservableCollection<tblStock> Stocks
{
   get
   {
      return _Stocks;
   }
   set
   {               
      _Stocks = value;
      OnPropertyChanged("Stocks");
   }
}

private ObservableCollection<tblClient> _Clients;
public ObservableCollection<tblClient> Clients
{
   get
   {
      return _Clients;
   }
   set
   {                
      _Clients = value;
      OnPropertyChanged("Clients");
   }
}

When I open a window there are two comboboxes bound to those properties. Those properties get set in the constructor of my view model class like so:

Clients = new ObservableCollection<tblClient>(wcf.GetClients());
Stocks = new ObservableCollection<tblStock>(wcf.GetStocks());    

It takes about 7 - 10 seconds sometimes to load these comboboxes when the window opens. I don't understand why so much time is needed when list counts are really small: 2 and 8 items. Here are the methods on wcf service:

List<tblClient> IService.GetClients()
{
   context = new PanErpLiteEntities();
   List<tblClient> cntnt = (from c in context.tblClients select c).ToList();
   return cntnt;
}

So my actual question is: what are the possible reasons of slowing down my application? I posted this question becouse it was to hard for me to find the answer on google when there are millions of reasons causing the application to work slow, so I'm here for the tips actually. I hope I made myself clear enough.

Brian
  • 5,069
  • 7
  • 37
  • 47
Stojdza
  • 445
  • 2
  • 10
  • 32
  • How long does it take to get the data over WCF? I'm not familiar with WCF, but have you tried making your Binding async? (in binding string IsAsync=True). – Alan Dec 18 '13 at 20:55
  • Profile the application. First determine if the wcf service is slow, or your bindings. – Charlie Brown Dec 18 '13 at 20:56
  • Is it possible that the service wasn't "spun up?" It could be that what you're seeing is service startup time. Try starting your application and then shutting it down immediately. Then start it again. If it starts up much faster the second time, that long delay you're seeing initially is most likely service startup time. – Jim Mischel Dec 18 '13 at 21:01
  • WCF is slow. Call on a background thread and keep the UI thread free to be responsive. Let the user know things are being loaded while they wait. Use paging if you are returning many clients and stocks. –  Dec 18 '13 at 21:40
  • I didn't mention that I use background workers for every wcf call. That keeps my UI responsive and I have loader giff indicating that the data is being loaded. But still it shouldn't be that slow for list of 2 items. – Stojdza Dec 18 '13 at 21:51
  • 1. Don't use background workers, use async/await or a Task with Synchronization Context to return to the UI thread before assigning the collections. – jmservera Dec 18 '13 at 23:14
  • 2. Don't use ToList() better return AsQueryable or AsEnumerable, so you can avoid one conversion step. – jmservera Dec 18 '13 at 23:19

1 Answers1

2

You found a million things on Google because there could be a million things that could be causing the slowness. What you need to do is learn how to identify where the slowness is, aka "Profiling".

There are 3 things you need to profile in your situation.

  • Where excatly your client program is hanging
  • The time it takes to a WCF request and reply to cross the wire
  • Where List<tblClient> IService.GetClients() is spending the most time.

For the first and third items you need a code profiler. There is one built in to Visual Studio, there is also many free and paid 3rd party ones available too.

For the 2nd item you can enable tracing in WCF itself, it can be as simple as adding the following to your App.config file on the server.

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\log\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

When you close your server next you can view the Traces.svclog in the "Service Trace Viewer" that comes with visual studio (you can also enable autoFlush and not need to wait for the service to be stopped to flush the buffers, but that will give you a performance hit).

Once you have all that new information you can come back here and make a new question like "How do I make the first request a WCF server fulfills faster?" or "Why does this Entity Framework query take so long" or something else entirely.

Community
  • 1
  • 1
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Thank you for quick replay and this really descriptive tips. As a beginner it was too difficult for me to start my research about possible cause of this problem. Thank you for point me about where to start. – Stojdza Dec 18 '13 at 21:10
  • Informative, but not an answer to the question. Should be a blogpost you link to in comments. Would be a good one, definitely. –  Dec 18 '13 at 21:41