如何修复 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.ReceiveDataRemoteJSRuntimeNULL,所以会报错。但是,我不明白为什么 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 语法不正确

如何修复“NameError:名称方法名称未定义”? [复制]

如何修复 vue-cli-service 漏洞?

如何修复这个正则表达式?

如何修复mysql.user表?