WebClient UploadProgressChanged called before sending any data and TotalBytesToSend is always -1

Endasil 1 Reputation point
2020-12-23T10:53:41.347+00:00

To summarize the problem, UploadProgressChanged is called several times, BytesSent goes up until it reached the file size but the file is not actually SENT during that time. The file is sent AFTER.

Tried this with sendDataAsync, sendDataTaskAsync, and UploadFileTaskAsync, with the same result. When the code comes to client.UploadFileTaskAsync, UploadProgressChanged will start to be called repeatedly and I can see by the Console.Writeline that it counts up to the size of the file I'm trying to send very quickly. After this program will stand still for a minute and end. Looking at this with fiddler shows that the file is not actually sent until after the count up is done.

I can see that the value of e.TotalBytesToSend is always -1. I looked this up in MSDN but can't find anything about the meaning of -1. I tried doing this call with curl and using that I can see in fiddler that the file is being uploaded when curl is counting up the bytes sent so apparently it is possible to get it right, I just don't see how.

This is probably related to the similar issue I posted about yesterday when I tried to get progress using httpwebrequest https://stackoverflow.com/questions/65391831/showing-file-upload-progress-with-httpwebrequest

Here is a minimal program that I can reproduce the issue with.

namespace filetransfertest
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using (var client = new WebClient())
            {
                client.UploadProgressChanged += UploadProgressChanged;
                var result = await client.UploadFileTaskAsync("https://postman-echo.com/post", "POST",
                    "C:/Dev/Unity/AltspaceVr test word/template.zip");
            }
        }

        private static void UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
        {
            Console.WriteLine("Sent: " + e.BytesSent + " Total: " + e.TotalBytesToSend);
        }
    }
}
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,354 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Timon Yang-MSFT 9,576 Reputation points
    2020-12-28T06:37:54.53+00:00

    I reproduced this problem using .net core.
    I used .net framework 4.7.2 before, as you can see, everything is normal.
    But when I use .net core for testing, the problem occurs. I use all the .net core versions (2.0, 2.1, 3.1 and .net 5) on my machine for testing, and the problem always exists.
    I did some investigation, and the problem may be in the private ProgressData class in this link, it exists as a field in WebClient: ProgressData
    In the .net framework, it is: ProgressData m_Progress;
    In .net core, it is modified to: private ProgressData? _progress;
    At the same time, other codes have also undergone a lot of changes, but I haven't found which part of the code changes cause TotalBytesToSend to always be -1, so I can't give you an accurate answer yet.
    I will continue to investigate. You can also ask questions in the GitHub repository of .net core and ask them to investigate.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.
    0 comments No comments