kristofferstrube / blazor.streams Goto Github PK
View Code? Open in Web Editor NEWA Blazor wrapper for the Streams browser API.
Home Page: https://kristofferstrube.github.io/Blazor.Streams/
License: MIT License
A Blazor wrapper for the Streams browser API.
Home Page: https://kristofferstrube.github.io/Blazor.Streams/
License: MIT License
It would more sense if the ReadableStreamReadResultInProcess.Value
property returned an IJSInProcessObjectReference
instead of an IJSObjectReference
. So let's do this.
We should utilize the great performance improvements that synchronous JSInterop brings in our implementation of ReadAsync
in ReadableStreamInProcess
.
We have already started some of this discussion in #3
Hello there! I have attempted to use your FileSystemAccess library in Blazor -- thank you for your work on all this. I have noticed that the stream returned by File.StreamAsync()
doesn't work in most scenarios I have tried (the file is acquired by using your APIs to show an "Open Window dialog" etc.). For example, when you have a 90MB file and just need to read 1KB of data, you would usually use
var buffer = new byte[1024];
int numberOfBytesRead = await stream.ReadAsync(buffer);
What this should do is read 1KB worth of data. What it actually does is throw an exception because the stream implementation doesn't respect the buffer length, as you can see from the implementation. Similarly, stream.Read()
(reading a single byte) doesn't work.
Here is the typical callstack:
Unhandled Exception:
System.ArgumentException: Destination is too short. (Parameter 'destination')
at KristofferStrube.Blazor.Streams.ReadableStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
at System.IO.StreamReader.ReadBufferAsync(CancellationToken cancellationToken)
at System.IO.StreamReader.ReadLineAsyncInternal(CancellationToken cancellationToken)
at BlazorLineFilter.Pages.Home.RunFilter() in D:\local-repositories\BlazorLineFilter\BlazorLineFilter\Pages\Home.razor:line 36
at BlazorLineFilter.Pages.Home.DoFiltering() in D:\local-repositories\BlazorLineFilter\BlazorLineFilter\Pages\Home.razor:line 46
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
at System.Threading.QueueUserWorkItemCallbackDefaultContext.Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.ThreadPool.BackgroundJobHandler()
The Destiniation is too short
message likely stems from the call to (await helper.InvokeAsync<byte[]>("byteArray", jSValue)).CopyTo(buffer);
.
For similar reasons, using something like new StreamReader(stream).ReadLineAsync()
doesn't work, unless you set the StreamReader
buffer size to a value that sits above the size of the buffer that the browser has chosen. For example, I can get consistent failures when I set the buffer size of a StreamReader
to 1MB but it works with 16MB. For now, that is, until Chrome changes its implementation and use larger buffers in the future :)
This is ultimately due to a difference between how JavaScript and C# choose to handle I/O: In C#, I get to choose the buffer size (the reader might still have its own buffer somewhere else for efficiency, but it'll handle whatever buffer size I give it). In Javascript, the browser gets to choose the buffer size and the read
functions just spits out chunk in the sizes that the browser has chosen.
One option for fixing this could be to add an internally buffer to the ReadableStream
itself or the reader types.
Because the constructors of our wrapper classes are internal we can't extend them in other libraries as is the case described in KristofferStrube/Blazor.FileSystemAccess#27.
To solve this and ensure that others can potentially extend this package we will make all constructors that are currently internal protected instead.
We should be able to set an AbortSignal
on StreamPipeOptions
, as the specs state.
Since we first created this library, Blazor.DOM
has been created, which implements a wrapper for AbortSignal
.
As described in KristofferStrube/Blazor.FileSystemAccess#23 we use a new structure that has InProcess
variants of wrapper classes that have synchronous methods or attributes.
I would want for it to be possible to convert the Blazor Server wrapper classes to the extended Blazor WASM InProcess variants through a cast or some method like AsInProcess()
, ToInProcessWrapper
. This might be possible to do by defining an explicit cast as an IJSObjectReference
can be casted to an IJSInProcessObjectReference
explicitly. The thing that might not be possible to do through a cast as that is synchronous is to create the inProcessHelper
which is needed for the InProcess
variants.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.