views:

100

answers:

3

I am designing an application which has the potential to hang while waiting for data from servers (either Database or internet) the problem is that I don't know how best to cope with the multitude of different places things may take time.

I am happy to display a 'loading' dialog to the user while access is happening but ideally I don't want this to flick up and disappear for short running operations.

Microsoft word appears to handle this quite nicely, as if you click a button and the operation takes a long time, after a few seconds you get a 'working..' dialog. The operation is still synchronous and you can't interrupt the operation. However if the same operation happens quickly you obviously don't get the dialog.

I am happy(ish) to devise some generic background worker thread handler and 99% of my data processing is already done in static atomic methods, but I would like to go best practice on this one if I can.

If anyone has patterns, code or suggestions I welcome them all

Cheers

A: 

Ideally you should be running any IO or non-UI processing either in a background thread or asynchronously to avoid locking up the UI.

mythz
+3  A: 

I would definitely think asynchronously using a pattern with 2 events. The first "event" is that you actually got your data from wherever/whenever you had to wait for it. The second event is a delay timer. If you get your data before this timer pops, all is well and good. If not, THEN you pop up your "I'm busy" and allow them to cancel the request. Usually cancel just mean "ignore" when you finally get the response.

No Refunds No Returns
+1  A: 

Microsoft word appears to handle this quite nicely, as if you click a button and the operation takes a long time, after a few seconds you get a 'working..' dialog. The operation is still synchronous and you can't interrupt the operation. However if the same operation happens quickly you obviously don't get the dialog.

If this is the behavior your want...

You could handle this, fairly easily, by wrapping a class around BackgroundWorker. Just time the start of the DoWork event, and the time to the first progress report. If a certain amount of time passes, you could show your dialog - otherwise, block (since it's a short process).

That being said, any time you're doing work that can be processed asynchronously, I'd recommend doing it that way. It's much nicer to never block your UI for a noticable interval, even if it's short. This becomes much simpler in .NET 4 (or 3.5 with Rx framework) by using the task parallel library.

Reed Copsey
How is that different from what I said except you have the overhead of the additional thread?
No Refunds No Returns
@No Refunds No Returns: There is no "overhead of an additional thread" here. The difference was in the approach. I gave him a different option, with no timers in the main thread, to handle this. Your solution requires a separate thread as well, since an asynchronous method invocation is done on a separate thread. I also suggested looking at Task<T> in TPL for asynchronous processing.
Reed Copsey
Yeah but with async code, the OS manages the thread instead of you. Your approach is more work for the developer and has more room for error.
No Refunds No Returns
@No Refunds No Returns: Not true - the OS is still managing the thread, via the ThreadPool, since the BackgroundWorker uses the thread pool. It's a safer approach, though, since BW automatically marshals the progress + completion events back to the UI thread, so you're less likely to get cross-thread UI complaints (no need to use Control.Invoke or Dispatcher.Invoke).
Reed Copsey