Kieran Senior
Kieran Senior

Reputation: 18220

Real-time thread updates issue

I'm working with many threads in a system where I know beforehand the total size of all files. When an observer is notified of a change by the subject it implicitly knows a file segment has been downloaded. I'll change this in the future as it's not explicit.

The problem I'm having is that my percentage indicator doesn't get updated if I deal with any other variables. Here's a snippet:

    public delegate void ChangeUI(object subject); 

    public void Update(object subject)
    {
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new ChangeUI(Update), new object[] { subject });
            return;
        }

        lock (otherlock)
        {
            toolstripStatus.Text = ((++totalDownloadedSegments / totalLengthAllFiles) * 100).ToString() + "% completed.";
        }

        // update the percentage indicator etc. (works fine)
        //toolstripStatus.Text = ((FileDownloader)subject).PercentageCompleted().ToString() + "% completed.";
    }

I'm using the this.InvokeRequired for thread-safety issues so ignore that. The line which is commented out works fine, but the one within the lock just doesn't work at all, with or without the lock. totalDownloadedSegments is a local variable, as is totalLengthAllFiles (which stays the same throughout and isn't modified).

As you can see, I'm not very good on the threading front. I basically want a percentage indicator to find out how much of all files I have downloaded in a percentage in the end.

Upvotes: 0

Views: 412

Answers (2)

Fuzz
Fuzz

Reputation: 1805

You've done a good job at discovering the InvokeRequired.

Be careful that totalDownloadedSegments and totalLengthAllFiles arent integers though

Because if you have 99/100 as an integer, it will become 0 !!! be very very careful

So instead of

((++totalDownloadedSegments / totalLengthAllFiles) * 100)

Try

(100 * ++totalDownloadedSegments) / totalLengthAllFiles

or cast them them to floats first!

Upvotes: 3

Darknight
Darknight

Reputation: 2500

From apps that I've done multi threading I think you need to do this:

 if (toolstripStatus.InvokeRequired)
  {
      toolstripStatus.BeginInvoke(new ChangeUI(Update), new object[] { subject });
      return;
  }
   //Update here, Lock Variables that are global and could be used by other threads.

Upvotes: 0

Related Questions