【发布时间】:2020-08-05 16:57:43
【问题描述】:
我的 C# 应用程序将文件上传到某些 API,我正在使用多部分请求,即我正在上传文件的 json 字符串和二进制文件,它适用于大多数文件,但对于极少数文件,它会给出异常,我意思是让我们尝试名为 50MB.zip 的文件
我得到了例外:
A task was canceled. ::: ::: System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
我的代码大致如下:
public async Task<Dictionary<string , string>> Upload(string filePath)
{
FileInfo fi = new FileInfo(FilePath);
string jsonString="some json string";
byte[] fileContents=File.ReadAllBytes(fi.FullName);
Uri webService = new Uri(url);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post , webService);
requestMessage.Method = HttpMethod.Post;
requestMessage.Headers.Add("Authorization" , "MyKey1234");
const string boundry = "------------------My-Boundary";
MultipartFormDataContent multiPartContent = new MultipartFormDataContent(boundry);
ByteArrayContent byteArrayContent = new ByteArrayContent(fileContents);
multiPartContent.Add(byteArrayContent);
requestMessage.Content = multiPartContent;
HttpClient httpClient = new HttpClient();
HttpResponseMessage httpResponse = await httpClient.SendAsync(requestMessage , HttpCompletionOption.ResponseContentRead , CancellationToken.None);
//exception in this line ^
return new Dictionary<string , string>();
}
调用者:
myDictionary = await Upload(filePath);
控制台应用的结构如下:
class Program
{
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
new MyClass().Start();
}
}
在MyClass:里面
public async void Start()
{
myDictionary = await Upload(filePath);
}
我想我没有正确使用异步,你能看到我错过了什么吗?有什么想法吗?
【问题讨论】:
-
您是否处理掉了您所有的
IDisposable对象? -
首先,不要每次都实例化新的
HttpClient对象。在大多数情况下,您应该只使用一个一遍又一遍。其次,这个异常通常是因为请求超时而发生的。尝试在您的 HttpClient 上设置更高的超时限制 -
此外,如果您将高级构建选项设置为使用最新的 C# 次要版本,则可以使用
static async Task Main方法,因此您可以使用await您的MainAsync()任务而不是使用阻塞Wait() -
使用调试器找出这个任务是如何被取消的。在 VS2017 中,使用 Debug > Windows > Exception Settings 并勾选 CLR exceptions 复选框。如果这导致调试器过于频繁地中断,那么您可以通过仅在 OperationCanceledException 上停止来使其更具体
标签: c# async-await