Callum Linington
Callum Linington

Reputation: 14417

C# Threading not finishing when code has finished

I Have this class to demonstrate my problem:

class Program
{
    static List<FileInfo> _foundFiles;
    static int _numberPadding = 0;
    static Thread newThread;

    static void Main(string[] args)
    {
        _foundFiles = new List<FileInfo>();

        _shouldStop = false;
        newThread = new Thread(new ThreadStart(StartSearch));
        newThread.Start();

        newThread.Join();

        Console.WriteLine("Finished");
        Console.ReadKey();
    }

    static volatile bool _shouldStop;

    static void StartSearch()
    {
        IterateFileSystemNon(new DirectoryInfo(@"D:\OLD Melman\Music Backup\iTunes 28-06-11\Music"));
    }

    static void IterateFileSystemNon(DirectoryInfo folder)
    {
        string pad = CreatePadding();

        Console.WriteLine("{0} Directory: {1}", pad, folder.Name);

        foreach (var dir in folder.GetDirectories())
            IterateFileSystemNon(dir);

        pad = CreatePadding();

        foreach (var file in folder.GetFiles())
        {
            if (file.Extension.Contains("mp3"))
            {
                _foundFiles.Add(file);

                Console.WriteLine("{0} File: {1}", pad, file.Name);
            }
        }

        _numberPadding = _numberPadding - 6;
    }

    static string CreatePadding()
    {
        _numberPadding = _numberPadding + 3;

        var stringRepOfPadding = new StringBuilder(_numberPadding);
        for (int i = 0; i < _numberPadding; i++)
        {
            stringRepOfPadding.Append(" ");
        }
        return stringRepOfPadding.ToString();
    }
}

I have theses questions:

  1. This works in a console app, but this doesn't work in a WindowsFormsApplication, it just goes straight to the Join statement, why is this?
  2. If the Join statement as Microsoft puts it "is suppose to block the current thread until the spawned thread has finished". Surely this defeats the object of multi-threading? In my WindowsFormsApplication, I don't want to block any thread while this thread is running it's task.
  3. Why do I need the Join. Surely when my Iteration void has completed iterating then the thread should just terminate?!
  4. How inside the new thread do I indicate it has finished so that it will close the thread?

Upvotes: 0

Views: 1531

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

  1. With Join you will hang UI thread. Use BackgroundWorker component to search files in background thread.
  2. Do not start thread and join to it. This is same as doing all work sequentially in one thread, because nothing is executed asynchronously in this case.
  3. You don't need Join (see p2). And using Join in UI thread is always bad idea.
  4. You don't need to indicate that thread is finished to close thread. Thread will exit when your thread delegate will finish execution. See Multithreading: Terminating Threads

Upvotes: 1

Kevin Pilch
Kevin Pilch

Reputation: 11605

  1. What do you mean by "Goes straight to the Join"? It's perfectly possible that a the initiating thread will hit the Join before the other thread even gets scheduled and hits a breakpoint. Can you elaborate on what the Windows Forms app is doing that isn't what you expect? Maybe there is an exception in that case that is causing the worker thread to exit prematurely?
  2. You don't have to call Join right away. The idea is that you start the thread, do whatever you want on the current thread and when you need the results from the second thread you call Join to wait for it to complete.
  3. Yes, the thread will end when the enumeration is finished.
  4. You just need to return from the method passed to the Thread constructor. (StartSearch in your case).

Upvotes: 0

Related Questions