Threading in .net - c#

I have a simple example of a winforms application where i choose a directory in a directory chooser and click a button to loop through the directory and copy each file in the directory into another directory.
i want to do the file copy on a background thread to avoid locking the GUI.
i am looking for the simplest solution to:
Create the background thread
Pass the source and destinations in
Get a callback on progress so i can show a progress bar on the GUI thread

I would recommend using the BackgroundWorker class.
Example.

In addition to the above answer, I'd add that the BackgroundWorker is ideal for this as it can give you progress updates too. Just make sure you prevent reentry - that is you need to prevent the situation where the user could start the background worker again before it has completed.

Related

Gif in Windows Form

I'm building a Windows Form application that manipulates a text file, the manipulation process takes time, so I creadted a Hidden PictureBox Control and I put an animated gif Image in it (Like a Progress Bar), and once the process starts I show the PictureBox, but the gif doesn't move cause it is on the same process I guess, is there any kind of solution...
Thanks
You should be doing your long processing in another thread, or simply by using a Background Worker.
msdn: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Plus, you can report any progress made to a progress bar...
Here's an example of use http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
Note that one of the main reasons why your GUI won't update when you're doing heavy computing, is the fact that the computing is done on the same thread as the UI in running on.
One solution is to use Threads, you fired tle process in one thread, then you show the Image... Here you have an excelent guide for beginners in Threads, Beginners Guide to Threading.
But onther easy solution, is to show the picturebox before the process start, so the picture shows in your form before the process take the control of the main Thread.

Winform application freeze

I have Winform application,which does some operation in loops (file access, copy file, ....). During theses operation, the application freeze completely, the job is done but impossible to move the main window or refresh the RichTextBox information (we display errors and the job in progress).
Do you have an idea how to do this ?
Thanks,
Consider using BackgroundWorker.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
It can both run your code in the background and report progress back to to the main
UI thread.
i suggest that you use a Background Worker and let the worker do the loops. i think your application read a file by line and added to the rich textbox control right?
this article will guide you in using BackGround Worker. or this
You can create separate thread and execute other task or may use background worker thread.

Why is FileUtilities.CopyFile wrapper for CopyFileEx interfering with winforms?

I’m using the FileUtilities.CopyFile wrapper for CopyFileEx from here http://msdn.microsoft.com/en-us/magazine/cc163851.aspx . I thought the CopyFileCallbackAction doesn’t get called until after the file is copied (I’ve tried copying a large file). And therefore asked this How do I get CopyFileEx to report back so I can cancel a file copy operation? question. But now I’ve found that it actually gets called many times, but for some reason it messes the form on which I’m trying to show the progress – the form doesn’t get updated until the copy is done. In fact, if I try running it in the Shown event handler – the form has empty boxes where buttons are supposed to be – until the copy is done. Why is that?
You will need to call CopyFileEx from a background thread. At the moment the call to CopyFileEx is blocking the UI thread. That's why the UI does not update.
The callback action is indeed called repeatedly. This is so that you can report to the user the progress of a long running file operation.
Just to be clear, this is what happens when you call CopyFileEx:
Enter CopyFileEx
Start copying
Call your callback
Continue copying
Call your callback
....
Return from CopyFileEx
For the entire duration of the file copy, the executing thread is busy copying the file rather than pumping the message queue. Although this is WinForms and not Win32, WinForms is a relatively lightweight wrapper around the standard Win32 GUI framework. Your message queue needs to be serviced regularly and so all long running tasks need to be run away from the UI thread.
One final point: remember that when you get your progress callback, you need to use Invoke or BeginInvoke when updating any UI. This is because code that updates UI needs to be run from the UI thread.

How do i add values to my list box while my background proccessing is going on?

I am creating an application.and i am scanning files of a drive to search a particular pattern
my progress bar is getting updated and at the end all the file names are listed in the list box.i want the all those files to be listed immediately as soon as its found that they contain the pattern.
I'm using BackgroundWorker
Use the ReportProgress method in combination with the ProgressChanged event. This type of scenario is exactly what they are intended for.
You can use ReportProgress method of background worker.
http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx
You would need to implement a foreground worker and invoke it from the background worker.
Ideally, you would be passing a list of any newly found files to the foreground worker.

How to show progress status for a long-time-consuming function?

I have a windows form simply like this: 1) a button when clicked will perform an operation taking a long time to complete, 2) a label showing how much percentage of the progress is going on.
In the long operation I mentioned, I write the code to update the Text property of the label but it doesn't work!
Please help me to show the progress status correctly.
You can take a look at the BackgroundWorker class (see the MSDN overview). It allows you to run some long-running operation in background and report progress updates (percentage) and completion from the background task to the user interface. Note that you'll need to calculate the progress percentage yourself.
However, the BackgroundWorker class takes care of other tricky aspects, such as sending your progress reports to the main GUI thread (where you can safely update the user interface).
Your going to want to create a worker thread that performs the task and occasionally reports its update to the form thread. If you do all of your work in the UI thread, your UI will be locked and won't update the progress/label correctly.
Before you start the worker thread, calculate the total number of steps you believe the process will take. Start the worker thread. After each unit of work, you Invoke an update method on the UI thread to increment the process.
You'll want to look at the BackgroundWorker class.
If your application will have several of these, I recommend creating a process interface (e.g. IProgressProcess). This interface will contain methods for executing a process and reporting updates. You will create all of your process classes by implementing from this interface. Write a control that contains a progress bar and accepts an IProgressProcess through a constructor or property. It can then use your custom process to execute and move along the progress bar. Then you can have your custom progress control send events when the process is complete or canceled.
This usually happens if you try to update the UI on the same thread where the operation is occurring. There are a couple of different ways that you could accomplish this.
You can update the UI with the BeginInvoke method.
You can use a BackgroundWorker component.
The reason that you don't see any change, is that the change causes a message to redraw the label, but the main thread is busy working so it doesn't respond to the message.
The simplest solution would be to just call the Application.DoEvents after updating the label. That works as a quick fix for your immediate problem, but it still will leave the application unresponsive in any other way.
The good solution would to start the operation in a separate thread. That way your main thread is free to handle messages while the operation is running. However working in a separate thread means a litte more work when communicating with the UI. If you want to update controls, you have to use the Invoke method to start a method that runs in the main thread so that it has access to the controls. Alternatively you can just update a variable in the thread, and have a timer control that periodically checks for changes in the variable and updates the label accordingly.

Categories

Resources