Sign in to follow this  
BTownTKD

[.net] C# backgroundWorker - how to pull logic out of UI

Recommended Posts

BTownTKD    205
I'm working on a fairly simple FTP utility, which connects to an embedded device and uploads/downloads a set of files via FTP. This utility is going to be slowly built upon to add more and more functionality over time, and I'd like to abstract as much logic as possible into a custom Class, but right now I have quite a bit of upload/download logic resting inside a backgroundWorker_DoWork event handler in my UI. I'm having a little bit of trouble conceptualizing a way to pull it out. I have a small custom structure that I pass around in the backgroundWorker's UpdateProgress() function - it stores the percent-completed for the current task, as well as the total percent for all tasks, and it contains a single string which describes the current task. I use all three variables in a status window (which contains the backgroundWorker). Maybe my view is skewed, but I was thinking of the backgroundWorker (and associated event handlers) as kind of a "UI" element; something to be avoided when pulling my logic into a separate Class. But I can't think of any other way to implement this, other than putting a backgroundWorker object in the class and hooking its "progress" events up to my UI...? Does that sound like the right approach? Edit: as an afterthought, I wanted to pose this question: currently I have a different backgroundWorker for each FTP operation (Upload/Download/etc) - there has to be a better way than that. Suggestions? [Edited by - BTownTKD on April 22, 2009 2:43:03 PM]

Share this post


Link to post
Share on other sites
DaWanderer    538
I would probably take a slightly different approach and design the FTP class with the following:

* Upload and Download methods that don't make use of BackgroundWorkers
* UploadProgress and DownloadProgress events that report the progress of their respective method above (they are fired from within the Upload and Download methods).

In the UI, I would attach to the UploadProgress method with an event handler that does a proper invoke onto the main UI thread to keep the user updated. When calling the Upload or Download methods, I would wrap them in a BackgroundWorker and let the previous event handler take care of updating the UI for me.

Overall, it'd look something like this:

using System.Windows.Forms;

// At the start of the program
FTPObject.UploadProgress += delegate(object sender, EventArgs e)
{
progresBar1.Invoke((MethodInvoker)delegate()
{
progressBar1.PerformStep();
});
};

// Somewhere else in the program
var worker = new BackgroundWorker();
worker.DoWorker += delegate(object sender, DoWorkEventArgs e)
{
FTPObject.Upload(...);
};

worker.RunWorkerAsync();



Hope this helps.

Share this post


Link to post
Share on other sites
BradSnobar    232
It doesn't matter if you use backgroundworker, beginInvoke, or threads. They are all basically different implementations that wrap up the same functionality. They all boil down to threads at the end of the day. The backgroundWorker, and the event delegate model both use the threadpool.

Anyway, moving on. Basically, you have the right idea. To link to different models like this, the best way is to surface some functionality from your ftp class by allowing the user to hoook some events. ie.) add an event to your ftp class.

OnProgressChanged(object sender, ftpEventArgs e)

Hook that event in the UI code, and then add the UI stuff in the event.

If you think about it, this is what you do all day long with the other controls and classes available to you in .Net.

Here is a link to view how to do some of this event stuff:
http://www.akadia.com/services/dotnet_delegates_and_events.html

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this