Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于.Net的Google API客户端:在请求失败时实现重试_C#_Google Api_Google Calendar Api_Google Api Dotnet Client - Fatal编程技术网

C# 用于.Net的Google API客户端:在请求失败时实现重试

C# 用于.Net的Google API客户端:在请求失败时实现重试,c#,google-api,google-calendar-api,google-api-dotnet-client,C#,Google Api,Google Calendar Api,Google Api Dotnet Client,当与google的API交互时,作为批处理请求一部分的请求失败时,如何实现重试。在他们的报告中,他们建议增加“指数退避”算法。我在他们的文档中使用了以下代码片段: UserCredential credential; using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBro

当与google的API交互时,作为批处理请求一部分的请求失败时,如何实现重试。在他们的报告中,他们建议增加“指数退避”算法。我在他们的文档中使用了以下代码片段:

UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets,
        new[] { CalendarService.Scope.Calendar },
        "user", CancellationToken.None, new FileDataStore("Calendar.Sample.Store"));
}

// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Google Calendar API Sample",
    });

// Create a batch request.
var request = new BatchRequest(service);
request.Queue<CalendarList>(service.CalendarList.List(),
     (content, error, i, message) =>
     {
         // Put your callback code here.
     });
request.Queue<Event>(service.Events.Insert(
     new Event
     {
         Summary = "Learn how to execute a batch request",
         Start = new EventDateTime() { DateTime = new DateTime(2014, 1, 1, 10, 0, 0) },
         End = new EventDateTime() { DateTime = new DateTime(2014, 1, 1, 12, 0, 0) }
     }, "YOUR_CALENDAR_ID_HERE"),
     (content, error, i, message) =>
     {
         // Put your callback code here.
     });
// You can add more Queue calls here.

// Execute the batch request, which includes the 2 requests above.
await request.ExecuteAsync();
UserCredential凭证;
使用(var stream=newfilestream(“client_secrets.json”、FileMode.Open、FileAccess.Read))
{
凭证=等待GoogleWebAuthorizationBroker.AuthorizationAsync(
GoogleClientSecrets.Load(stream.Secrets),
新[]{CalendarService.Scope.Calendar},
“用户”,CancellationToken.None,新文件数据存储(“Calendar.Sample.Store”);
}
//创建服务。
var service=new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer=凭证,
ApplicationName=“谷歌日历API示例”,
});
//创建批处理请求。
var请求=新批处理请求(服务);
request.Queue(service.CalendarList.List(),
(内容、错误、i、消息)=>
{
//把你的回拨码放在这里。
});
request.Queue(service.Events.Insert(
新事件
{
Summary=“了解如何执行批处理请求”,
Start=neweventdatetime(){DateTime=newdatetime(2014,1,1,10,0,0)},
End=neweventdatetime(){DateTime=newdatetime(2014,1,1,12,0,0)}
},“您的日历ID在此”),
(内容、错误、i、消息)=>
{
//把你的回拨码放在这里。
});
//您可以在此处添加更多队列呼叫。
//执行批处理请求,其中包括上述2个请求。
等待请求。ExecuteAsync();

这里有一个简单的助手类,可以很容易地为Google在API错误页面上提到的许多情况实现指数退避:

如何使用:

  • 编辑下面的类,以便在上设置时包含客户端密码和应用程序名称
  • 在应用程序启动时(或当您要求用户授权时),调用
    GCalAPIHelper.Instance.Auth()
  • 您可以在任何地方调用Google日历API(例如Get、Insert、Delete等),而是通过执行以下操作来使用此类:
    GCalAPIHelper.Instance.CreateEvent(event、calendarId)(您可能需要根据需要将此类扩展到其他API端点)
使用谷歌;
使用Google.api.Auth.OAuth2;
使用Google.api.Calendar.v3;
使用Google.api.Calendar.v3.Data;
使用Google.api.Services;
使用Google.api.Util.Store;
使用制度;
使用System.IO;
使用System.Linq;
Net系统;
使用系统文本;
使用系统线程;
使用静态Google.api.Calendar.v3.CalendarListResource.ListRequest;
/*======================================================================================
*此文件用于实现具有指数回退的Google Calendar.NET API端点。
* 
*如何使用:
*-安装Google Calendar.NETAPI(nuget.org/packages/Google.API.Calendar.v3)
*-编辑下面的类,以在需要时包含客户端密码和应用程序名称
*建立在https://console.developers.google.com
*-在应用程序启动时(或当您要求用户授权时),请拨打
*GCalAPIHelper.Instance.Auth();
*-您可以在任何地方调用Google日历API(例如获取、插入、删除等),
*而是通过执行以下操作来使用该类:
*GCalAPIHelper.Instance.CreateEvent(事件,日历ID);(您可能需要扩展
*根据您的需要将该类添加到其他API端点)
*======================================================================================
*/
名称空间APIHelper
{
公共类GCalAPIHelper
{
#区域单态
私有静态GCalAPIHelper实例;
公共静态GCalAPIHelper实例
{
收到
{
if(实例==null)
实例=新的GCalAPIHelper();
返回实例;
}
}
#端区单态
#区域私有财产
专用日历服务服务{get;set;}
私有字符串[]范围={CalendarService.Scope.Calendar};
private const string CLIENTSECRETSTRING=“YOUR_SECRET”//在此处粘贴您的JSON客户端密码。别忘了转义特殊字符!
private const string APPNAME=“您的\u应用程序\u名称”;//在此处粘贴您的应用程序名称
#endregion私有财产
#区域构造函数和初始化
公共GCalAPIHelper()
{
}
公共void身份验证(字符串credentialsPath)
{
if(服务!=null)
回来
用户凭证;
byte[]byteArray=Encoding.ASCII.GetBytes(CLIENTSECRETSTRING);
使用(var流=新内存流(byteArray))
{
凭证=GoogleWebAuthorizationBroker.AuthorizationAsync(
GoogleClientSecrets.Load(stream.Secrets),
范围,
Environment.UserName,
取消令牌。无,
新文件数据存储(credentialsPath,true))。结果;
}
服务=新日历服务(新BaseClientService.Initializer()
{
HttpClientInitializer=凭证,
ApplicationName=APPNAME
});
}
#endregion构造函数和初始化
#区域私有方法
private Trense DoAction with ExponentialBackoff(CalendarBaseServiceRequest)
{
返回DOActionWithExponentalBackoff(请求,新的HttpStatusCode[0]);
}
private Trense DoActionWithExponentialBackoff(CalendarBaseServiceRequest请求、HttpStatusCode[]其他BackoffCodes)
{
int延迟=100;
while(delay<1000)//如果延迟超过1秒,请放弃
    private async Task<TResponse> DoActionWithExponentialBackoff<TResponse>(DirectoryBaseServiceRequest<TResponse> request)
    {
        return await DoActionWithExponentialBackoff(request, new HttpStatusCode[0]);
    }

    private async Task<TResponse> DoActionWithExponentialBackoff<TResponse>(DirectoryBaseServiceRequest<TResponse> request, HttpStatusCode[] otherBackoffCodes)
    {
        int timeDelay = 100;
        int retries = 1;
        int backoff = 1;

        while (retries <= 5) 
        {
            try
            {
                return await request.ExecuteAsync();
            }
            catch (GoogleApiException ex)
            {
                if (ex.HttpStatusCode == HttpStatusCode.NotFound)
                    return default;
                else if (ex.HttpStatusCode == HttpStatusCode.Forbidden || //Rate limit exceeded
                    ex.HttpStatusCode == HttpStatusCode.ServiceUnavailable || //Backend error
                    ex.Message.Contains("That’s an error") || //Handles the Google error pages like https://i.imgur.com/lFDKFro.png
                    otherBackoffCodes.Contains(ex.HttpStatusCode))
                {
                    //Common.Log($"Request failed. Waiting {delay} ms before trying again");
                    Thread.Sleep(timeDelay);
                    timeDelay += 100 * backoff;
                    backoff = backoff * (retries++ + 1);
                }
                else
                    throw ex;  // rethrow exception
            }
        }

        throw new Exception("Retry attempts failed");
    }