Question

I'm using WebClient to post data to a web service and I thought I'd add the progress event that's available but I can't get it to work properly. I'm trying to upload files ranging from 200k to 6Mb, but when the event is triggered, it is triggered numerous times in a few seconds and displays the percentage up to high 90's i.e. 91,95,98, etc... but never 100%.

Then I wait for a minute, minute and a half and it eventually it displays the remaining percentage all the way to 100.

Here is my function (Note that I've removed the code to convert my object to json or xml).

    public static async Task<string> PostDataAsync<T>(string uriString, T data, WebHeaderCollection headers, ContentType contentType, string wrappedName)
    {
        using (WebClient client = new WebClient())
        {
            client.Encoding = System.Text.Encoding.UTF8;
            client.Headers = headers;
            client.Headers[HttpRequestHeader.Accept] = contentType == ContentType.Json ? "application/json" : "application/xml";
            client.Headers[HttpRequestHeader.ContentType] = contentType == ContentType.Json ? "application/json" : "application/xml";

            client.UploadDataCompleted += client_UploadDataCompleted;
            client.UploadProgressChanged += client_UploadProgressChanged;

            //Convert data to json/xml                

            byte[] requestBuffer = Encoding.UTF8.GetBytes(postData);
            byte[] responseBuffer = await client.UploadDataTaskAsync(uriString, "POST", requestBuffer);

            client.UploadDataCompleted -= client_UploadDataCompleted;
            client.UploadProgressChanged -= client_UploadProgressChanged;

            return System.Text.Encoding.UTF8.GetString(responseBuffer);
        }
    }

Any ideas why this is happening? Could it be because it's an async function, or static?

Is there a way to get this to display the percentage as the data is uplodated?

Thanks.

Update

Added UploadProgressChanged event as requested:

    static void client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
    {
        Console.WriteLine(e.BytesSent.ToString() + " - " + e.TotalBytesToSend.ToString() + " - " + e.ProgressPercentage.ToString());
    }

Update

Below is some data I've saved to file. You can clearly see 2 wrong behaviours:

  1. 0 TO 49% in less than 1/2 second
  2. Percentage goes down and then back up (less important)
  3. After 1m25s, it jumps from 49% to 100% with no events generated in between but it clearly highlights a problem where:

a) events are generated too early b) events are generated too quickly c) events are generated correctly

Time: 00:45:08.1141619 - BS: 8192 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 0

Time: 00:45:08.1141619 - BS: 16384 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 0

Time: 00:45:08.1171616 - BS: 24576 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 0

Time: 00:45:08.5374381 - BS: 8282112 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 48

Time: 00:45:08.5374381 - BS: 8290304 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 48

Time: 00:45:08.5284373 - BS: 7577600 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 43

Time: 00:45:08.5374381 - BS: 8306688 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 48

Time: 00:45:08.5374381 - BS: 8331264 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 48

Time: 00:45:08.5414384 - BS: 8617984 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 49

Time: 00:45:08.5414384 - BS: 8625111 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 50

Time: 00:45:08.5404378 - BS: 8536064 - TBS: 8625111 - BR: 0 - TBR: -1 - %: 49

Time: 00:46:33.2813979 - BS: 8625111 - TBS: 8625111 - BR: 545 - TBR: 545 - %: 100

PS: There were 957 entries in my file, so I obviously didn't paste them all, but 956 of these were generates in 1/2 second or so. The last line was generated after 1m25s. Doesn't make sense!!

No correct solution

OTHER TIPS

I had a look at the source code for WebClient and found this:

if (progress.TotalBytesToReceive < 0 && progress.BytesReceived == 0)
{
    progressPercentage = progress.TotalBytesToSend < 0 ? 0 : progress.TotalBytesToSend == 0 ? 50 : (int)((50 * progress.BytesSent) / progress.TotalBytesToSend);
}
else
{
    progressPercentage = progress.TotalBytesToSend < 0 ? 50 : progress.TotalBytesToReceive == 0 ? 100 : (int)((50 * progress.BytesReceived) / progress.TotalBytesToReceive + 50);
}

Here is the link.

It looks like the first 50% is based on the bytes sent and the last 50% on the bytes received. So if your web service responds instantly with "Ok" then your progress will jump to 100%.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top