如何修复 RemoteJSDataStream NullReferenceException?
Posted
技术标签:
【中文标题】如何修复 RemoteJSDataStream NullReferenceException?【英文标题】:How to fix RemoteJSDataStream NullReferenceException? 【发布时间】:2022-01-10 14:12:49 【问题描述】:通过 HttpClient 将 .NET 6 / Blazor 服务器端 中的文件作为 StreamContent 以 parallel 上传到 API 时出现错误。以下是精简后的代码和错误的全文:
P.S. 框架传给Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSDataStream.ReceiveData
的RemoteJSRuntime
是NULL
,所以会报错。但是,我不明白为什么 NULL
被通过了。我无法捕捉它、熄灭它、以某种方式影响它。
P.S.S. 和 ApiClient 无关,可以正常使用。该错误仅在第一个页面加载后启动时发生,奇怪的是,在重新加载页面并重新启动后,一切正常。
源代码:
https://github.com/abberdeen/BlazorServer.ParallelFileUpload
相关问题:
https://github.com/dotnet/aspnetcore/issues/38854
public void AddFilesToUploadQueue(List<FileUploadDto> files)
foreach (var item in files)
fileUploadQueue.Enqueue(item);
for (int i = 0; i < files.Count; i++)
Task t = factory.StartNew(() => UploadOne());
tasks.Add(t);
private async Task UploadOne()
semaphore.WaitOne();
FileUploadDto item;
if (!fileUploadQueue.TryDequeue(out item))
return;
// Make HttpRequest
await UploadFileAsync(item);
semaphore.Release();
blazor.server.js:1 [2021-12-06T19:07:53.123Z] Error: System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSDataStream.ReceiveData(RemoteJSRuntime runtime, Int64 streamId, Int64 chunkId, Byte[] chunk, String error)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c__11`1.<<InvokeAsync>b__11_0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost.ReceiveJSDataChunk(Int64 streamId, Int64 chunkId, Byte[] chunk, String error)
输出窗口中的错误:
System.TimeoutException: Did not receive any data in the allotted time.
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
at System.IO.Pipelines.PipeReaderStream.ReadAsyncInternal(Memory`1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSDataStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.CopyFileDataIntoBuffer(Int64 sourceOffset, Memory`1 destination, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.IO.Stream.<CopyToAsync>g__Core|29_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
at System.Net.Http.StreamToStreamCopy.<CopyAsync>g__DisposeSourceAsync|1_0(Task copyTask, Stream source)
at System.Net.Http.HttpContent.<CopyToAsync>g__WaitAsync|56_0(ValueTask copyTask)
at System.Net.Http.MultipartContent.SerializeToStreamAsyncCore(Stream stream, TransportContext context, CancellationToken cancellationToken)
at System.Net.Http.HttpContent.<CopyToAsync>g__WaitAsync|56_0(ValueTask copyTask)
at System.Net.Http.HttpContent.<CopyToAsync>g__WaitAsync|56_0(ValueTask copyTask)
at System.Net.Http.HttpConnection.SendRequestContentAsync(HttpRequestMessage request, HttpContentWriteStream stream, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at ~~~~~BlazorApp.Services.AuthHttpClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in ~~~~~BlazorApp\Services\AuthHttpClientHandler.cs:line 27
at System.Net.Http.Handlers.ProgressMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
at ~~~~~BlazorApp.Services.FileUploadApiService.PostAndReportProgress(String url, MultipartFormDataContent formData, String guid, EventHandler`1 progressHandler, CancellationToken cancellationToken) in ~~~~~BlazorApp\Services\FileUploadApiService.cs:line 106
--- End of inner exception stack trace ---
at ~~~~~BlazorApp.Services.FileUploadApiService.PostAndReportProgress(String url, MultipartFormDataContent formData, String guid, EventHandler`1 progressHandler, CancellationToken cancellationToken) in ~~~~~BlazorApp\Services\FileUploadApiService.cs:line 122
at ~~~~~BlazorApp.Services.FileUploadApiService.ChatUploadFileAsync(StreamContent file, Int32 chatId, String guid, EventHandler`1 progressHandler, CancellationToken cancellationToken) in ~~~~~BlazorApp\Services\FileUploadApiService.cs:line 59
at ~~~~~BlazorApp.Services.FileUploadManager.UploadFileAsync(FileUploadDto item) in ~~~~~BlazorApp\Services\FileUploadManager.cs:line 171
at ~~~~~BlazorApp.Services.FileUploadManager.<StartUploadTask>b__18_0() in ~~~~~BlazorApp\Services\FileUploadManager.cs:line 108
【问题讨论】:
【参考方案1】:感谢您的样品。我能够重现System.TimeoutException
。
我无法使用此代码重现错误(FileUploadManager
仅更改)。你可以试试这个吗?
public async void AddFilesToUploadQueue(IReadOnlyList<IBrowserFile> files)
lock (fileUploadQueue)
foreach (var item in files)
fileUploadQueue.Enqueue(item);
for (int i = 0; i < files.Count; i++)
IBrowserFile? file = null;
lock(fileUploadQueue)
fileUploadQueue.TryDequeue(out file);
tasks.Add(UploadOneFile(file));
//await Task.WhenAll(tasks);
protected async Task UploadOneFile(IBrowserFile file)
await semaphoreSlim.WaitAsync();
try
using (var readStream = file.OpenReadStream(int.MaxValue))
var streamContent = fileUploadService.CreateStreamContent(readStream, file.Name, file.ContentType);
var result = await fileUploadService.UploadFileAsync(streamContent);
finally
semaphoreSlim.Release();
【讨论】:
以上是关于如何修复 RemoteJSDataStream NullReferenceException?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复多项目 GWT 设置中的 RPC 错误 IncompatibleRemoteServiceException?
如何修复 @p0 附近删除 Top n 命令的 SqlException 语法不正确