当我将某些文件发送到Google驱动器时,有时有时会得到空的ResponseBody。
这是随机发生的,大多数文件都已发送,但是十分之一的文件返回空的ResponseBody。
我搜索了此内容,但是仅存在有关距离为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为null?为何只发生几次?
更新:
我编辑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 Error Code,因为这是与exponential backoff相关的问题。由于您要发出的并发请求数量众多,因此会发生这种情况。
因此,在您的代码中,您将需要应用一些逻辑来避免该问题。例如[algorithm:
如果请求失败,请等待1 + random_number_milliseconds秒,然后重试请求。
如果请求失败,请等待2 + random_number_milliseconds秒,然后重试请求。
如果请求失败,请等待4 + random_number_milliseconds秒,然后重试请求。
依此类推,直到最大退避时间。
其中:
等待时间为min((((2 ^ n)+ random_number_milliseconds),maximum_backoff),每次迭代n都会增加1(请求)。
random_number_milliseconds是随机的毫秒数大于或等于1000。这有助于避免出现许多客户的情况在某些情况下同步并立即重试,发送同步波浪中的请求。的价值每个重试请求后都会重新计算random_number_milliseconds。
maximum_backoff通常为32或64秒。适当的值取决于用例。
基于alberto vielma的答案,我的代码现在可以正常工作,看起来像这样:
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();
//solution: Truncated exponential backoff
if (result.Status != UploadStatus.Completed)
{
var rdn = new Random();
var waitTime = 0;
var count = 0;
do
{
waitTime = (Convert.ToInt32(Math.Pow(2, count)) * 1000) + rdn.Next(0, 1000);
Thread.Sleep(waitTime);
result = request.Upload();
count++;
} while (count < 5 && (result.Status != UploadStatus.Completed));
}//end solution
}
if (result.Status != UploadStatus.Completed)
throw result.Exception; //Doesn't get here anymore
var fileUploaded = request.ResponseBody;
return fileUploaded.WebContentLink;
});
}