c# - 在使用 Google Drive .NET API 上传文件时,有时会出现 Null ResponseBody
问题描述
当我将一些文件发送到谷歌驱动器时,我有时会得到空的 ResponseBody。
这是随机发生的,大多数文件都已发送,但十分之一的文件返回 null ResponseBody。
我搜索了这个,但只有关于 aways 得到 response null here和here的问题
我的代码:
await UploadFileAsync(...); //exception here
public Task<string> UploadFileAsync(DriveService driveService, string LocalPath, string gdriveFileName, string GDriveFolder, IProgress<long> progress)
{
return Task.Run(() =>
{
var folderId = GetDirectoryOrCreateIfNotExist(driveService, GDriveFolder);
var file = CreateGDriveFile(gdriveFileName, folderId);
IUploadProgress result = null;
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(LocalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
request = driveService.Files.Create(file, stream, "image/jpeg");
request.ChunkSize = ResumableUpload.MinimumChunkSize * 4;
request.ProgressChanged += (p) => progress.Report(p.BytesSent * 100 / stream.Length);
request.Fields = "id, webContentLink, name";
result = request.Upload();
}
if (request == null)
throw new Exception("O request é nulo");
if (request.ResponseBody == null)
throw new Exception("O ResponseBody é nulo"); //Throw here sometimes
var fileUploaded = request.ResponseBody;
return fileUploaded.WebContentLink;
});
}
private string GetDirectoryOrCreateIfNotExist(DriveService driveService, string folderName)
{
var folder = GetFolderIdByName(driveService, folderName).FirstOrDefault();
if (folder == null)
{
folder = CreateGDriveDirectory(driveService, folderName);
AplyPermissionToFile(driveService, folder);
}
return folder;
}
private File CreateGDriveFile(string fileName, string folderName = null)
{
var file = new File()
{
Name = fileName
};
if (folderName != null)
{
file.Parents = new List<string>
{
folderName
};
}
return file;
}
为什么 ResponseBody 为空?为什么这种情况只发生几次?
更新:
我编辑 UploadFileAsync(),检查 UploadStatus,现在我得到:
The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
Internal Error [500]
Errors [
Message[Internal Error] Location[ - ] Reason[internalError] Domain[global]
]
更新的代码:(见 result.Status != UploadStatus.Completed)
public Task<string> UploadFileAsync(DriveService driveService, string LocalPath, string gdriveFileName, string GDriveFolder, IProgress<long> progress)
{
return Task.Run(() =>
{
var folderId = GetDirectoryOrCreateIfNotExist(driveService, GDriveFolder);
var file = CreateGDriveFile(gdriveFileName, folderId);
IUploadProgress result = null;
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(LocalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
request = driveService.Files.Create(file, stream, "image/jpeg");
request.ChunkSize = ResumableUpload.MinimumChunkSize * 4;
request.ProgressChanged += (p) => progress.Report(p.BytesSent * 100 / stream.Length);
request.Fields = "id, webContentLink, name";
result = request.Upload();
}
if (result.Status != UploadStatus.Completed) //check status, now it's throwing here sometimes
throw result.Exception;
if (request == null)
throw new Exception("O request é nulo");
if (request.ResponseBody == null)
throw new Exception("O ResponseBody é nulo");
var fileUploaded = request.ResponseBody;
return fileUploaded.WebContentLink;
});
}
有人能帮我吗?
解决方案
您收到500 错误代码,因为这是与指数退避相关的问题。由于您尝试发出的并发请求的数量,它会发生。
因此,在您的代码中,您需要应用一些逻辑来避免该问题。例如这个算法:
如果请求失败,请等待 1 + random_number_milliseconds 秒,然后重试请求。
如果请求失败,请等待 2 + random_number_milliseconds 秒,然后重试请求。
如果请求失败,请等待 4 + random_number_milliseconds 秒,然后重试请求。
依此类推,直到maximum_backoff 时间。
在哪里:
等待时间为 min(((2^n)+random_number_milliseconds), maximum_backoff),每次迭代(请求)时 n 递增 1。
random_number_milliseconds 是小于或等于 1000 的随机毫秒数。这有助于避免许多客户端在某些情况下同步并一次重试,以同步波发送请求的情况。每次重试请求后都会重新计算 random_number_milliseconds 的值。
maximum_backoff 通常为 32 或 64 秒。适当的值取决于用例。
推荐阅读
- docker - 无法在 docker swarm 覆盖网络中更改容器的静态 IP
- python - Python:为 ConvNet 创建具有多个通道的时间序列
- php - 计算帖子的平均评分
- javascript - 简单的篮球运动 Javascript
- angularjs - 如何通过指令将数据从 HTML 传递到控制器?
- python - Predict() 与 sklearn LogisticRegression 和 RandomForest 模型总是预测少数类 (1)
- elasticsearch - 查询多个单词时,通配符无法按预期工作
- java - 为 make OS X 设置 JDK 路径
- deep-learning - 改进FCN和R-CNN深度学习模型的修改思路
- reactjs - 一个选择的其他选择选项的onchange应该改变,我应该得到提交警报的数据