2

I have a backgroundworker that copies some files. After it finishes copying the files, I want to launch an application. The problem I am running into is that while the files are copying, it calls the code to launch the application, so it runs into a file in use error. Is there a check I can do to ensure that a certain method is only called when the background worker has completed?

private void LaunchApplication(string targetPath, string targetExecutable)
    {
            CopyFiles();

            Process.Start(Path.Combine(targetPath, targetExecutable));
    }

CopyFiles is called within the DoWork method of the BackGroundWorker. I want this to completely finsih before Process.Start... is called. Now I have several executables tied to several buttons, so I can't put the Process.Start... in the RunWorkerCompleted event.

Xaisoft
  • 45,655
  • 87
  • 279
  • 432
  • 3
    Are you making use of the [RunWorkerCompleted](http://msdn.microsoft.com/en-gb/library/system.componentmodel.backgroundworker.runworkercompleted.aspx) event? – DGibbs Apr 19 '13 at 14:41
  • You could check that the files have copied before running the application. – Sam Leach Apr 19 '13 at 14:45
  • @DGibbs - Yes, but the problem there is that I have several applications that can be launched and I can't tell which one it is until the user clicks one of the launch buttons. – Xaisoft Apr 19 '13 at 14:47
  • @SamLeach - How can I determine this? – Xaisoft Apr 19 '13 at 14:48
  • @Xaisoft I'm not sure I understand... couldn't you just prevent the buttons from doing anything if the worker isn't complete? – DGibbs Apr 19 '13 at 14:49
  • @DGibbs - I'll put a snippet of code which might help understand the problem – Xaisoft Apr 19 '13 at 14:50
  • @SamLeach - Would one option might be to have a private variable that is set to true after the file copy is done and then only call Process.Start... if that is true? – Xaisoft Apr 19 '13 at 15:01
  • Use FileSystemWatcher.NotifyFilter Property. http://msdn.microsoft.com/en-gb/library/system.io.filesystemwatcher.notifyfilter.aspx – Sam Leach Apr 19 '13 at 15:05
  • Is the code that calls `CopyFiles()` run in the same thread as the BG worker? I'm still not seeing a reason why you can't just set a flag to true when the run worker completed event is fired, then use this in `LaunchApplication`? – DGibbs Apr 19 '13 at 15:06
  • http://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice – Sam Leach Apr 19 '13 at 15:07
  • I'll join in here - I think we need to see the bigger picture here. How do the button presses related to the copy files. You state that "After it finishes copying the files, I want to launch an application", but then you say "I have several executables tied to several buttons, so I can't put the Process.Start... in the RunWorkerCompleted event". This is a bit confusing in itself! Could you expand your example?! – Bertie Apr 19 '13 at 15:33
  • `if (!bgw.IsBusy) { Process.Start(...); }` – kschieck Apr 19 '13 at 18:00

1 Answers1

1

If you put CopyFiles() in a background thread the next line of code will be executed, so in your case, I would not use a background worker. Instead I would block until the copy files completes and then start the application. Put up some sort of window telling your uses to wait a bit.

If you need to wait and still use a background worker, then CopyFiles() should be in the DoWork handler and Process.Start should be BackgroundWorker.RunWorkerCompleted event.

MSDN on RunWorkerCompleted

RunWorkerCompleted

Stack Overflow Example on Completed:

Run Worker Completed Sample Code

Also, you can create a global mutex to ensure only one launch is happening at a time so if you get multiple launches only one will be processed.

Stack Overflow Global Mutex Question

Community
  • 1
  • 1
Jon Raynor
  • 3,804
  • 6
  • 29
  • 43
  • The problem I have with putting Process.Start in RunWOrkerCompleted is that there are about 6 buttons that launch different applications and I have no idea which one the user clicked. – Xaisoft Apr 19 '13 at 15:40
  • @Xaisoft - You could add click handlers for each button, or one handler for all of them. The handler will have a 'object sender' argument that is passed. Cast it to a Button and you could find the name of the button if you are using the generic handler approach. – Jon Raynor Apr 19 '13 at 15:49
  • So do you copy the files when the button is pressed or just open the exe? if you're copying the files then you could pass the executable path as an argument to the background worker. If you are just opening the exe on button click then just check if the background worker is busy with `bgw.IsBusy` – kschieck Apr 19 '13 at 18:02