Reputation: 1761
I have an issue that I can solve by running my code synchronously and it works great but to reduce wait time for my users I need to run async for this method as I have a few other tasks that need to run as well but I omitted for testing purposes but use the same procedures. I get an error in my Azure download method (DriveItemDownloadAsync
) I created as shown:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'IServiceProvider'.at Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException()
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Microsoft.Identity.Web.TokenAcquisitionAspnetCoreHost.GetEffectiveAuthenticationScheme(String authenticationScheme)
at Microsoft.Identity.Web.TokenAcquisitionAspnetCoreHost.GetOptions(String authenticationScheme, String& effectiveAuthenticationScheme)
at Microsoft.Identity.Web.TokenAcquisition.GetAuthenticationResultForUserAsync(IEnumerable1 scopes, String authenticationScheme, String tenantId, String userFlow, ClaimsPrincipal user, TokenAcquisitionOptions tokenAcquisitionOptions) at Microsoft.Identity.Web.DefaultAuthorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(IEnumerable
1 scopes, AuthorizationHeaderProviderOptions downstreamApiOptions, ClaimsPrincipal claimsPrincipal, CancellationToken cancellationToken)
at Microsoft.Identity.Web.TokenAcquisitionAuthenticationProvider.AuthenticateRequestAsync(HttpRequestMessage request)
at Microsoft.Graph.AuthenticationHandler.SendAsync(HttpRequestMessage httpRequestMessage, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at Microsoft.Graph.HttpProvider.SendRequestAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)}
The code I am using in my controller is as follows. If I remove the Task and make this run synchronously no error happens.
Task ReportTask = new Task(async () => {
var reportPathOneDrive = "path.docx";
var reportPathBox = "path.docx";
var FileInfo = await oneDrive.DriveItemInfoAsync(SharedDriveID, reportPathOneDrive, "path");
var memoryStream = await oneDrive.DriveItemDownloadAsync(SharedDriveID, reportPathOneDrive, "path");
MemoryStream memoryStreamBox = new MemoryStream();
memoryStream.CopyTo(memoryStreamBox);
memoryStream.Position = 0;
memoryStreamBox.Position = 0;
//add to email
var attachment = new ARMS.Models.FileAttachment
{
FileName = FileInfo.Name.ToString(),
ContentType = FileInfo.File.MimeType.ToString(),
ContentBytes = memoryStream.ToArray()
};
attachments.Add(attachment);
var uploadBox = await boxDrive.UploadFileAsync(BoxARMSFolderID, memoryStreamBox, reportPathBox);
});
ReportTask.Start();
List<Task> documentTasks = new List<Task> { ReportTask };
await Task.WhenAll(documentTasks);
The error will appear in this function here:
public async Task<MemoryStream> DriveItemDownloadAsync(string DriveID, string PathOrDriveItemID, string SearchType)
{
var tries = 0;
var maxRetries = 1;
Stream response = null;
var MemoryStream = new MemoryStream();
while (tries <= maxRetries)
{
tries++;
try
{
if (SearchType == "path")
{
response = await _graphServiceClient.Me.Drives[DriveID].Root
.ItemWithPath(PathOrDriveItemID)
.Content
.Request()
.GetAsync();
}
else if (SearchType == "id")
{
response = await _graphServiceClient.Me.Drives[DriveID]
.Items[PathOrDriveItemID]
.Content
.Request()
.GetAsync();
}
response.CopyTo(MemoryStream);
MemoryStream.Position = 0;
tries = maxRetries + 1;
}
catch (ServiceException svcex) when (svcex.Message.Contains("Continuous access evaluation resulted in claims challenge"))
{
try
{
Console.WriteLine($"{svcex}");
string claimChallenge = WwwAuthenticateParameters.GetClaimChallengeFromResponseHeaders(svcex.ResponseHeaders);
_consentHandler.ChallengeUser(initialScopes, claimChallenge);
}
catch (Exception ex2)
{
_consentHandler.HandleException(ex2);
}
}
}
return MemoryStream;
}
The response line where it actually goes to use MS Graph is what draws the error. I know I need to be careful with memory streams in async but I thought I was using them correctly in this sense with the lambda function. In fact this is the first time I have used lambda in a New Task() object so I am thinking that could be an issue?
Upvotes: 0
Views: 131