1
public delegate void FileEventHandler(string file);
public event FileEventHandler fileEvent;

public void getAllFiles(string path)
{
    foreach (string item in Directory.GetDirectories(path))
    {
        try
        {
            getAllFiles(item);
        }
        catch (Exception)
        { }
    }

    foreach (string str in Directory.GetFiles(path, "*.pcap"))
    {
        // process my file and if this file format OK raised event to UI and add the file to my listbox
        FileChecker fileChecker = new FileChecker();
        string result = fileChecker.checkFIle(str);
        if (result != null)
            fileEvent(result);
    }
}

private void btnAddDirInput_Click(object sender, EventArgs e)
{
        ThreadStart ts = delegate { getAllFiles(pathToSearch); };
        Thread thread = new Thread(ts);
        thread.IsBackground = true;
        thread.Start();
}

I want to wait until thread has finish its job and then update my UI

user2214609
  • 4,713
  • 9
  • 34
  • 41
  • 10
    Where's your thread? – CodingIntrigue Aug 29 '13 at 14:07
  • 2
    http://stackoverflow.com/questions/1584062/how-to-wait-for-thread-to-finish-with-net?rq=1 Check this out – Nick Aug 29 '13 at 14:10
  • I am calling getAllFiles() via another thread from the mail UI – user2214609 Aug 29 '13 at 14:13
  • It's hard to tell exactly what you need unless we see more information. You definitely need to lock something or add a mutex, we just can't tell what. – Heckman Aug 29 '13 at 14:15
  • 1
    Can't you use a BackGroundWorker? They were made for this purpose. – Rik Aug 29 '13 at 14:16
  • within fileChecker.checkFIle is the thread? – Koryu Aug 29 '13 at 14:16
  • why not use a worker add an event handler "OnWorkDone", call it when thread is finished and update the ui? Here is a good thread example to create a splash screen: [link](http://mrbool.com/how-to-make-a-splash-screen-in-csharp/26598) – Koryu Aug 29 '13 at 14:20
  • See my update, added the thread – user2214609 Aug 29 '13 at 14:21
  • Why not Thread.Join()? – Naren Aug 29 '13 at 14:26
  • @Naren Because then you block the UI thread. – Servy Aug 29 '13 at 14:26
  • use Async and Await http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx – Constantin Aug 29 '13 at 14:26
  • You shouldn't be swallowing exceptions as you are in `getAllFiles`. If you have a try/catch then you should be handling the exceptions (at the very, very least, you should be logging them somewhere so that you know they're happening) and if you can't handle them then it's better to just let them bubble up. – Servy Aug 29 '13 at 14:28
  • @Servy But the OP said "I want to wait until thread has finish its job and then update my UI".I can't understand it. – Naren Aug 29 '13 at 14:29
  • @Naren You need to ensure that the UI is updated when the background work is finished *without* blocking the main thread. If you've ever done any desktop style programming at all, it would be a problem you are very frequently faced with, and there are *lots* of resources on the subject all over the internet. – Servy Aug 29 '13 at 14:37
  • @Servy Thanks ,I misunderstood the question. – Naren Aug 29 '13 at 14:38

2 Answers2

5

You can use the Task Parallel Library, rather than explicit tasks, along with the asynchrony language features to do this very easily:

private async void btnAddDirInput_Click(object sender, EventArgs e)
{
    await Task.Run(() => getAllFiles(pathToSearch));
    lable1.Text = "all done!";
}
Servy
  • 202,030
  • 26
  • 332
  • 449
  • If this runs in a separate thread, the Text attribute assignment will throw a runtime exception. – Jonathan Henson Aug 29 '13 at 14:30
  • @JonathanHenson Look at the method. This is the button click event handler. It runs in the UI thread. – Servy Aug 29 '13 at 14:31
  • Sorry didn't notice that. Await will not block the UI thread either? – Jonathan Henson Aug 29 '13 at 14:32
  • @JonathanHenson No, it will not. It will schedule the remainder of the method as a continuation of the awaited task and then return control back to the caller. – Servy Aug 29 '13 at 14:33
  • +1 for realising the requirement is not necessarily to wait, but to simply update the UI once the task has completed, and providing a succint solution. – Daniel Kelley Aug 29 '13 at 14:45
3

Why not use Tasks?

await Task.Run(() => getAllFiles(pathToSearch));

Your method will be run on a separate thread, freeing your main thread to keep the UI responsive. As soon as the task completes, the control will return to your UI thread.

Edit: Don't forget to mark your button_click method as async void

dcastro
  • 66,540
  • 21
  • 145
  • 155
  • just curious, is it possible to update a progress bar this way? – Koryu Aug 29 '13 at 14:29
  • @Koryu You would use the `Progress` class to update a progress bar. – Servy Aug 29 '13 at 14:31
  • Do you mean running a task that periodically updates a progress bar? You can, but I don't think tasks were designed for this purpose. – dcastro Aug 29 '13 at 14:32
  • 2
    @dcastro The TPL does indeed have a mechanism for handling it. It is the `Progress` class, as I said before. That's the intended mechanism for solving that problem with this style of programming. – Servy Aug 29 '13 at 14:34
  • Thanks @Servy, I wasn't aware of the `Progress` class. If anyone else is interested in this, http://msdn.microsoft.com/en-us/library/hh193692.aspx and http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx will help. – dcastro Aug 29 '13 at 14:37
  • ty, sounds interesting, i usually use backround worker with progress bar. didnt know it would work with a task. i just found this [example on code project](http://www.codeproject.com/Articles/129447/Progress-Reporting-in-C-5-Async) – Koryu Aug 29 '13 at 14:38