6 Replies - 688 Views - Last Post: 08 September 2011 - 02:00 AM Rate Topic: -----

#1 falcon eyes  Icon User is offline

  • D.I.C Head

Reputation: -4
  • View blog
  • Posts: 53
  • Joined: 16-April 07

Copying files issue

Posted 04 September 2011 - 03:23 PM

Hi every one
I have wrote a program to backup a selected folders to another place and works ,but there's an issue and it's during the copy process i can't interact with the application until it's finished from copying for example i can't exit the application or press any button or even moving the application window,so if any one has a solution for this issue i will be appreciate.
Is This A Good Question/Topic? 0
  • +

Replies To: Copying files issue

#2 Gavisann  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 103
  • View blog
  • Posts: 382
  • Joined: 01-July 11

Re: Copying files issue

Posted 04 September 2011 - 03:27 PM

Use a Background Worker or a Thread.

Run your copying method in the worker or thread and the UI will not freeze.

If you need any further explanation, let us know.

This post has been edited by Gavisann: 04 September 2011 - 03:28 PM

Was This Post Helpful? 2
  • +
  • -

#3 falcon eyes  Icon User is offline

  • D.I.C Head

Reputation: -4
  • View blog
  • Posts: 53
  • Joined: 16-April 07

Re: Copying files issue

Posted 05 September 2011 - 01:20 AM

Thanks Gavisann
Yes pls i want to learn how to execute each of the two methods

pls i want to alert that my program is written in C#
Was This Post Helpful? 0
  • +
  • -

#4 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 924
  • View blog
  • Posts: 926
  • Joined: 30-September 10

Re: Copying files issue

Posted 05 September 2011 - 03:09 AM

*
POPULAR

Hi,

Firstly, I just want you to be aware that you are performing an I/O bound operation, and both the Thread class and the BackgroundWorker class are technically only for compute bound operations. Thus, by using them for I/O bound operations, you're going to end up with a background thread that is blocked doing nothing for the majority of the time, which isn't ideal and it is wasteful, as threads aren't cheap. You should technically favour asynchronous I/O methods :)

However, unless you're aiming to create a high-performing application, asynchronous I/O will end up being more trouble than it's worth in this case (since there are no built in async file copying methods in the framework, so you'd have to make you're own. Then you've go the problem of creating the new files, which cannot be done asynchronously without the use of a background thread etc), so using a dedicated background thread will do the job perfectly fine (and probably better in terms of keeping the UI responsive, since you have to create the files synchronously, as no Win32 method exists for asynchronous file creation) :)

I just wanted to make you aware of this 'conflict' so you are aware of it in the future, and I'll point you in the direction of a more I/O oriented example of asynchronous file copying later, just for reference :).

Anyway, on to the techniques Gavisann mentioned (plus a few more) for running the operation on a background thread:

Thread class

This class creates a brand new thread from scratch. You can use it like this:

Thread thread = new Thread(() => <call method that copies folders here>);
thread.Start(); //start the thread running



Now, the method you specify after the '=>' will be run on a background thread, keeping the UI thread free, and thus keeping your application responsive.


ThreadPool class

Unless the copying operation is very long running (and if you chose to use the Thread class instead of BackgroundWorker), I would suggest you use the ThreadPool class instead. It handles threads in a more efficient manner and rather than creating a thread from scratch, there is a chance that you're just reusing an old thread from the thread pool.

You use that like this:

ThreadPool.QueueUserWorkItem((o) => <call method that copies folders here>);


That will add your work item to the thread pool's work queue, and sometime in the future, a thread from the pool will grab that work item, and execute it. Thus achieving the same effect as the Thread class, but in a (quite possibly) more efficient manner.

Task class

Even better than the Thread and ThreadPool classes, you could use the Task class if you are using .NET 4.0. The Task class uses the thread pool behind the scenes, but makes use of certain optimizations that the CLR team made to the thread pool. Plus, Tasks provide some very nice features that make certain common tasks much easier for us, as developers.

To use it:

Task.Factory.StartNew(() => <call method that copies folders here>); 


Your method will now be executed on a background thread from the thread pool.

BackgroundWorker class

This is what I would probably advise you use if you are new to multithreading. It actually uses the thread pool behind the scenes to grab a thread to execute your work on, so you gain the efficiency benefits of the thread pool, but also get keep ease of use.

To use it, you first create an instance of the BackgroundWorker class:

BackgroundWorker worker = new BackgroundWorker();


(Or, as BackgroundWorker inherits from Component, you can drag an instance of the BackgroundWorker from the design toolbox in VisualStudio, which has the same effect, except the worker will be called 'backgroundWorker1' instead of 'worker').

Next, you need to subscribe to some events (i'll assume your using my explicit instance called 'worker' above). The DoWork event first...

The DoWork event handler method is the method that contains your work that you want executing on a background thread. It looks something like this:

private void worker_DoWork(object sender, DoWorkEventArgs e) {
    <call your method to copy files here>
}


You subscribe to the DoWork event (so that method gets called when the event is fired) like this:

worker.DoWork += worker_DoWork;


Right, now you need to know when the work has completed. You do this with another event called RunWorkerCompleted. The handler method that is called when that event is fired looks something like this:

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
           <code to run when work is done here>
        }




And you subscribe to that event like this:

worker.RunWorkerCompleted += worker_RunWorkerCompleted;


Now, when you want to start the worker, (and thus call worker_DoWork()), you call this method on the worker instance:

worker.RunWorkerAsync();


and that will start the worker going, and you code will execute on a background thread from the thread pool.

In a similar way, you can use the ProgressChanged event (and the ReportProgress() method) to report progress back to the UI thread.


Take your pick from them. I would usually strongly advise using the Task class where possible, but the BackgroundWorker class will still probably be the easiest to use if you're quite new to this. Have a look through the links provided by Gavisann, and have a go at implementing one of the techniques yourself, and see how you get on. Report back if you get stuck :)


Asynchronous I/O method

Now, as promised, a method for copying files in the way that accounts for the fact that it is an I/O bound operation (thus not wastefully blocking threads) can be seen here.

See here also for the MSDN reference. The BeginXXX() and EndXXX() methods are examples of asynchronous I/O methods. Unfortuantely, as I mentioned, there are no asynchronous I/O methods for copying files, which is why async I/O is more trouble than it is worth in this example, but should technically be favoured in I/O bound scenarios where the methods exist (from a raw efficiency and performance standpoint, perhaps not so much from a code readability standpoint ;))

This post has been edited by CodingSup3rnatur@l-360: 05 September 2011 - 04:26 AM
Reason for edit:: Fixed code tags

Was This Post Helpful? 8
  • +
  • -

#5 falcon eyes  Icon User is offline

  • D.I.C Head

Reputation: -4
  • View blog
  • Posts: 53
  • Joined: 16-April 07

Re: Copying files issue

Posted 05 September 2011 - 06:20 AM

thanks very much,
i will try BackgroundWorker class,but i have a question,
when i register to the ProgressChanged event could i know the current file being copy by adding some code in its handler function.
Was This Post Helpful? 0
  • +
  • -

#6 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 924
  • View blog
  • Posts: 926
  • Joined: 30-September 10

Re: Copying files issue

Posted 05 September 2011 - 06:57 AM

Yes. To raise the ProgressChanged event, you call the ReportProgress() method (ensuring the .WorkerReportsProgress is set to true).

You can pass the percentage (representing the progress), and you can also pass a second arguement, represent the current state. You could pass the current file name in as that argument:

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
     string fileName = e.UserState.ToString(); //access file name here
}

private void worker_DoWork(object sender, DoWorkEventArgs e) {
     //copy files
     this.worker.ReportProgress(<current percentage progress>, "filename"); //passing percentage and current file name
}


Was This Post Helpful? 3
  • +
  • -

#7 falcon eyes  Icon User is offline

  • D.I.C Head

Reputation: -4
  • View blog
  • Posts: 53
  • Joined: 16-April 07

Re: Copying files issue

Posted 08 September 2011 - 02:00 AM

thanks again CodingSup3rnatur@l-360
i have tried it and it work perfect
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1