这是我使用Google API进行身份验证的方式:
Private Function DoAuthentication(ByRef rStrToken As String, ByRef rParameters As OAuth2Parameters) As Boolean
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
m_Scopes.Add(CalendarService.Scope.Calendar)
Try
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("XXXXX.Application")).Result()
If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
credential.RefreshTokenAsync(CancellationToken.None)
End If
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "xxx"
}
m_Service = New CalendarService(initializer)
rStrToken = credential.Token.AccessToken.ToString()
rParameters.AccessToken = credential.Token.AccessToken
rParameters.RefreshToken = credential.Token.RefreshToken
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthentication")
Return False
End Try
Return True
End Function
然后在我的Main
:
Dim parameters As New OAuth2Parameters
If (DoAuthentication(strToken, parameters)) Then
iResult = RESULT_SUCCESS_OAUTH
Else
Return RESULT_FAILED_OAUTH
End If
然后继续。问题是,有时即使“身份验证”成功完成,它也开始运行其余代码。然后我得到一个例外:
2020-11-30 18:47:03.6762|ERROR|GoogleAuthandSync.Program|AddEventsToCalendarXML|System.IO.IOException: The process cannot access the file 'C:\Users\USERNAME\AppData\Roaming\XXXXX.Application\Google.Apis.Auth.OAuth2.Responses.TokenResponse-user' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
如何验证/刷新令牌,并确保我们准备好进行操作,以便此异常停止?并非总是如此。
(为了安全起见,我在上面的代码/错误文本中将令牌文件重命名为)。
我应该使用Await
关键字吗?
If credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default) Then
Await credential.RefreshTokenAsync(CancellationToken.None)
End If
那会有所作为吗?我注意到在此示例代码中,他们使用await
。
鼓励我在GitHub上问这个问题(请参阅讨论)。
事实证明,我并不需要像以前那样使用RefreshTokenAsync
。我能够简化我的代码,并将其转换为如下所示的Async
方法:
Private Async Function DoAuthenticationAsync() As Task(Of Boolean)
Dim credential As UserCredential
Dim Secrets = New ClientSecrets() With {
.ClientId = m_strClientID,
.ClientSecret = m_strClientSecret
}
Try
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(Secrets, m_Scopes,
"user", CancellationToken.None,
New FileDataStore("XXXXX.Application"))
' Create the calendar service using an initializer instance
Dim initializer As New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "XXXXX"
}
m_Service = New CalendarService(initializer)
Catch ex As Exception
' We encountered some kind of problem, perhaps they have not yet authenticated?
' Can we isolate that as the exception?
m_logger.Error(ex, "DoAuthentication")
Return False
End Try
Return True
End Function
然后,我不得不将Main
函数中的所有代码移到一个任务中:
Private Async Function Run() As Task(Of Integer)
...
End Function
最后,我进行了Main
如下调整:
Public Function Main() As Integer
Return RunAsync.Result
End Function