3

My professor gave me this semi-pseudo code. He said I should find a mistake somewhere in this code's logic. At the moment I can not find anything, what could be wrong. Could you please give me some hints about what could be wrong? I'm not asking for an answer because I would like to find it myself, but some hints in what direction I should look would be awesome.

class Program
{
    int progressValue = 0;
    int totalFiles = 0;
    int i = 0;
    bool toContinue = true;

void MasterThread()
{
    Thread thread1 = new Thread(Worker1);
    Thread thread2 = new Thread(Worker2);
    Thread progressThread = new Thread(ProgressThread);

    thread1.Start();
    thread2.Start();
    progressThread.Start();
}

void Worker1()
{
    string[] files = Directory.GetFiles(@"C:\test1");
    totalFiles += files.Length;
    foreach (string file in files)
    {
        Encryption.Encrypt(file);
        i++;
        progressValue = 100 * i / totalFiles;
    }
    toContinue = false;
}

void Worker2()
{
    string[] files = Directory.GetFiles(@"C:\test2");
    totalFiles += files.Length;
    foreach (string file in files)
    {
        Encryption.Encrypt(file);
        i++;
        progressValue = 100 * i / totalFiles;
    }
    toContinue = false;
}

void ProgressThread()
{
    while (toContinue == true)
    {
        Update(progressValue);
        Thread.Sleep(500);
    }
  }
}
2
  • Concurrent access to the variable? Commented Sep 3, 2016 at 9:36
  • 1
    Thank you all for answers and your time that you have spent answering and trying to help me! I will definitely look into all of things you have pointed! Thanks! Commented Sep 3, 2016 at 12:59

5 Answers 5

3
toContinue = false;

This is set at the end of the first completing thread - this will cause the ProgressThread to cease as soon as the first thread completes, not when both threads complete. There should be two separate thread completion flags and both should be checked.

Sign up to request clarification or add additional context in comments.

Comments

1

To add to the good answers already provided, I'm being a little thorough, but the idea is to learn.

Exception Handling

Could be issues with exception handling. Always check your program for places where there could be an unexpected result.
How will this code behave if the value of this variable is not what we are expecting?
What will happen if we divide by zero?
Things like that.

Have a look at where variables are initialized and ask yourself is there a possibility that this might not initialize in the way it's expected?

Exception Handling (C# Programming Guide)

Method Calls

Also check out any libraries being used in the code. e.g. Encryption.
Ask yourself, are these statements going to give me an expected result? e.g.

string[] files = Directory.GetFiles(@"C:\test1");

Will this return an array of strings?
Is this how I should initialise an array of strings?

Question the calls: e.g.

 Update(progressValue);

What does this really do?

Class Library

Threading

How will it work calling three threads like that.
Do they need to be coordinated?
Should threads sleep, to allow other actions to complete?

Also as for accessing variables from different threads.
Is there going to be a mess of trying to track the value of that variable?
Are they being overwritten?

Thread Class
How to: Create and Terminate Threads (C# Programming Guide)

Naming Conventions

On a smaller note there are issues with naming conventions in C#. The use of implicit typing using the generic var is preferred to explicit type declarations in C#.

C# Coding Conventions (C# Programming Guide)

I am not saying that there are issues with all these points, but if you investigate all of these and the points made in the other answers, you will find all the errors and you will obtain a better understanding of the code you are reading.

Comments

1

Here are the items:

  1. There is nothing holding on to the "MasterThread" - so it's hard to tell if the program will instantly end or not.
  2. Access is made to totalFiles from two threads and if both do so at the same time then it is possible that one or the other may win (or both may partially update the value) so there's no telling if you have a valid value or not. Interlocked.Add(ref totalFiles, files.Length); should be used instead.
  3. Both worker threads also update i which could also become corrupted. Interlocked.Increment(ref i); should be used instead.
  4. There is no telling if Encryption.Encrypt is thread-safe. Possibly a lock should be used.
  5. The loop in ProgressThread is bad - Thread.Sleep should always be avoided - it is better to have an explicit update call (or other mechanism) to update progress.
  6. There is no telling if Update(progressValue); is thread-safe. Possibly a lock should be used.

Comments

0

There are a few; I'll just enumerate the two obvious ones, I'm supposing this is not an exercise of how to code precise and correct multithreaded code.

You should ask yourself the following questions:

  1. progressValue should measure progress from zero to hundred of the total work (a progress value equal to 150 seems a little off, doesn't it?). Is it really doing that?
  2. You should not stop updating progressValue (Update(progressValue)) until all the work is done. Are you really doing that?

1 Comment

Thank you for highlighting these two, I will look into them. Actually subject is called Multithreaded programming, so it might be some mistakes in the logic of multithreaded part. Can you see any?
0

I don't know too much about multithreading but ill try to give a coupe of hints. First look at the global variables, what happens when you access the same variable in different threads?

Besides the hints on the other answer I can't find anything else "wrong".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.