我正在使用.NET 4.0来尝试利用HttpClient提供的功能。目的是使用HTTP Verb“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'..
正如您将注意到我已从我的代码中删除了所有使用块,关闭或处置语句等。对于我的生活,我无法弄清楚出了什么问题!我已经使用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状态代码。