0

我正在使用 .NET 4.0 来尝试利用 HttpClient 提供的功能。目的是使用 HTTP 动词“PUT”将大小约为 10.5 MB 的特定文件上传到远程服务器。远程服务器使用 node.js。

我编写了一个小型控制台应用程序(.NET 4.0 完整而不是客户端配置文件)
我使用的笔记本电脑没有 .NET 4.5 或 Visual Studio 2012
我安装了将这些 NuGet 包添加到它以启用带有进度更新的异步上传功能

<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="4.0.20710.0" targetFramework="net40" />
  <package id="Microsoft.Net.Http" version="2.0.20710.0" targetFramework="net40-Client" />
  <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
</packages>

然后我编写了一个简单的函数来进行同步上传(UploadFile)。此功能按预期工作并正确上传文件。

名为 UploadFileAsync 的下一个方法尝试使用 HttpClient,但在上传的 55-70% 之间失败。Visual Studio 2010 引发了一系列异常。第一个通常不同,范围从

WebException
"The request was aborted: The request was cancelled"

到各种其他类型。然而,第二个例外总是可以预测的并且是相同的。这是

ObjectDisposedExceptoin
Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.

最后这是链中的最后一个异常

IOException

    Unable to read data from the transport connection: Cannot access a disposed object.
    Object name: 'System.Net.Sockets.Socket'..

你会注意到我已经从我的代码中删除了所有 using 块、close 或 dispose 语句等。对于我的生活,我无法弄清楚出了什么问题!我已经尝试过使用 HttpClient 的 PutAsync 和 SendAsnyc 方法。他们唯一的区别是第一个异常发生了变化。

这是代码块

void UploadFile(string fileToUpload)
        {
            //string fileToUpload = @"F:\\upload_file.txt";
            using (FileStream rdr = new FileStream(fileToUpload, FileMode.Open))
            {
                HttpWebRequest req = null;
                Stream reqStream = null;
                try
                {
                    req = (HttpWebRequest)WebRequest.Create(url);

                    req.Method = "PUT";
                    req.Headers.Add("x-myheader", "163333.zip");
                    req.ContentType = "application/octet-stream";
                    req.ContentLength = rdr.Length;
                    req.AllowWriteStreamBuffering = false;
                    req.Timeout = 1000000;
                    reqStream = req.GetRequestStream();
                    Console.WriteLine(rdr.Length);
                    byte[] inData = new byte[rdr.Length];

                    // Get data from upload file to inData 
                    int bytesRead = rdr.Read(inData, 0, (int)rdr.Length);

                    // put data into request stream
                    reqStream.Write(inData, 0, (int)rdr.Length);
                    rdr.Close();

                    req.GetResponse();
                    // after uploading close stream 
                    reqStream.Close();

                }
                catch (Exception e)
                {

                }
                finally
                {
                    rdr.Close();

                    req.GetResponse();
                    // after uploading close stream 
                    reqStream.Close();

                }
            }


        }



        void UploadFileAsync(string fileToUpload)
        {


            //string fileToUpload = @"F:\\upload_file.txt";
            FileStream rdr = new FileStream(fileToUpload, FileMode.Open, FileAccess.Read, FileShare.Read, 8192, true);
            //newfs rdr = new newfs(fileToUpload, FileMode.Open);
            HttpClientHandler clientHandler = new HttpClientHandler();
            ProgressMessageHandler progressHandler = new ProgressMessageHandler(clientHandler);
            HttpClient client = new HttpClient(progressHandler);

            try
            {


                client.DefaultRequestHeaders.Add("x-myheader", "163333.zip");

                HttpRequestMessage requestPayLoad = new HttpRequestMessage(HttpMethod.Put, url);

                long totalFileSize = rdr.Length;
                Console.WriteLine(totalFileSize);

                int? previousPercentage = null;

                progressHandler.HttpSendProgress += (sender, args) =>
                {
                    if (!previousPercentage.HasValue || previousPercentage != args.ProgressPercentage)
                        Console.WriteLine(args.ProgressPercentage);
                    previousPercentage = args.ProgressPercentage;

                };

                requestPayLoad.Content = new StreamContent(rdr);

                //requestPayLoad.Content = new FileContent(fileToUpload);
                //var task = client.PutAsync<byte[]>(url, rdr, new BinaryMediaTypeFormatter());
                var task = client.SendAsync(requestPayLoad);
                task.Wait();


            }
            catch (Exception e)
            {

            }
            finally
            {
                //rdr.Close();
                client.Dispose();
                //req.GetResponse();
                //// after uploading close stream 
                //reqStream.Close();

            }

        }

更新

看来该文件确实可以到达服务器。这基本上意味着 ProgressHandler 报告的百分比不正确,并且错误出现在上传的最右端。Fiddler 显示 HTTP 200 状态代码。

4

0 回答 0