Authenticating / Refreshing Google API access token and avoiding a “file in use” exception?
See original GitHub issueI have been encouraged to ask my question that I raised on StackOverflow here.
In short, I have been having occasional issues when trying to sync with a Google Calendar.
The basic functionality is:
- Authenticate
- Delete existing calendar events
- Add new calendar events
The delete / add tasks are done using batching.
As mentioned, sometimes I get an exception like:
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)
This is how I authenticate:
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
I was wondering if this line is wrong:
credential.RefreshTokenAsync(CancellationToken.None)
Should it be proceeded with await
? I wondered if it might still be refreshing the token file whilst we are continuing to try and use it. I can provide further code snippets as needed.
As mentioned, it usually works and this is a sporadic issue.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:24 (5 by maintainers)
Top GitHub Comments
You don’t need to do any of that, there’s a Revoke method on the UserCredential. You can do something like the following (I’m writing directly on the comment so there might be some syntax errors).
This will both revoke the token with the Google Auth platform and delete it from the local file.
Yes, given that yours is a console application, it should be fine as it is now. Just calling Wait() and Result is redundant. You can just do: