views:

81

answers:

2

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.

A: 

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.
Darknight
`toolStripStatus` is a UI object, it doesn't have `InvokeRequired` available on it.
Kezzer
I'm not sure, but when I used other controls e.g. list boxes etc., I have used this approach works fine for hundreds of concurrent threads updating it...
Darknight
+3  A: 

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!

Fuzz
This is definitely on the right track. They're currently of type `long` because I'm getting the information from type `FileInfo` anyway. Casting them to `float` and doing it your way gives me something better, although not right.
Kezzer