views:

71

answers:

1

Being new to using threads etc in UI's, can I ask is the following simple design seem OK. Refer to diagram image at link here

In particular:

a) use of backgroundworker & backgroundworker ProgressChanged to have the aggregator work on a separate thread. So I would need a custom class/type that had all the data I'd need to pass back from the aggregator thread to the UI thread I assume.

b) create a separate thread within the aggregator to ensure that the SharpPCap/WinPCap callback method is in a different thread. So this Capture Manager thread writes packet results to a shared Buffer. I'm assuming here that if the code can see the buffer variable that they can both access it, irrespective of which thread they're running in?

thanks

+1  A: 

I have a couple suggestions:

  1. I wouldn't recommend using a BackgroundWorker and ProgressChanged for this. Given that you want to "poll and aggregate" every 1 second, I'd recommend just using a Timer (probably a DispatcherTimer). You can use Dispatcher.BeginInvoke to marshal the calls back onto the UI thread, if you have this run in a separate thread (you can also use a UI-thread based timer, if you want).

  2. I'd recommend using a ConcurrentQueue<T> to hold your packet data, instead of a list. This will prevent you from needing locking around your list. If you must stick to versions of .NET <4, you can use a List<T>, but you'll need to synchronize access to it (lock on some object to protect read/write operations in the list). Both threads will be able to use the same collection, provided it's thread safe or synchronized correctly.

Reed Copsey
Tks. Re 1) would the aggregator need knowledge of the UI though for this? If I wanted to reuse it for other UIs what would you recommend here? An event approach somehow?
Greg
I agree with most of Reed's comments, except that I would recommend using a `System.Timers.Timer` for the polling, and use a `Task` scheduled to `TaskScheduler.FromCurrentSynchronizationContext` to marshal the calls back to the UI thread. This has the advantage of being non-WPF specific.
Stephen Cleary
I still quite see the advantage of us of Dispatcher over BackgroundWorker? What's the main reason in my case why I should run with it over BackgroundWorker as a mechanism to get updates back to the UI layer?
Greg
@Greg: Using ReportProgress in BW is really kind of not using it for its intended purpose. This causes your code to be unclear, as well as being more difficult to write than to just do your code again. Stephen's suggestion of using TaskScheduler is a very good one - but you'll need to make sure to pass your background thread the scheduler created in the UI context up front. (I was going to write that originally, but it required a little extra explanation, so I left it out...)
Reed Copsey
Greg
@Greg: I'd make "Aggregator" a timer - and have it spawn the thread to run "Capture manager". The "Aggregator" timer could use the Dispatcher (via BeginInvoke) to talk to the UI thread. (Just saw your edit - I'd probably not worry about drift too much if you're polling every second....)
Reed Copsey