Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
I'm not sure if it's an actual bug since I couldn't have found any mentioning about thread safety/parallel capabilities of IJSRuntime. But from what I've seen in sources it's somewhat like an expected usage. And apart from this byte[] case it seems to work in our project.
Here is a sample code. The idea behind it is simple. We've had a consecutive processing, but one day decided to improve on performance by running it in parallel using Task.WhenAll. In an actual code it's a different arrays on JS side of course.
await JsRuntime.InvokeVoidAsync("eval", """
window.setArray = (async (streamReference) => {
const arrayBuffer = await streamReference.arrayBuffer();
window.testArray = new Uint8Array(arrayBuffer);
});
""");
var array = new byte[50 * 1024];
new Random(Guid.NewGuid().GetHashCode()).NextBytes(array);
using var arrayStream = new MemoryStream(array);
using var arrayStreamReference = new DotNetStreamReference(arrayStream);
await JsRuntime.InvokeVoidAsync("setArray", arrayStreamReference);
await JsRuntime.InvokeVoidAsync("eval", """
window.getArray = ((start, length) => {
return window.testArray.slice(start, length);
});
""");
var tasks = Enumerable.Range(0, 10).Select(async _ => {
var builder = new List<byte>();
var start = 0;
while (true) {
var chunk = await JsRuntime.InvokeAsync<byte[]>("getArray", start, start + 30 * 1024);
if (chunk.Length == 0)
break;
builder.AddRange(chunk);
start += chunk.Length;
}
if (!array.SequenceEqual(builder))
throw new Exception();
});
await Task.WhenAll(tasks);
For me it fails on first run already. But sometimes it may be required to run in 2-3 times to get an exception.
Microsoft.JSInterop.JSException: An exception occurred executing JS interop: JSON serialization is attempting to deserialize an unexpected byte array.. See InnerException for more details.
---> System.Text.Json.JsonException: JSON serialization is attempting to deserialize an unexpected byte array.
at Microsoft.JSInterop.Infrastructure.ByteArrayJsonConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
at System.Text.Json.Serialization.JsonConverter1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.JsonConverter
1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.JsonConverter`1.ReadCoreAsObject(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo, ReadStack& state)
at System.Text.Json.JsonSerializer.Read[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo)
at Microsoft.JSInterop.JSRuntime.EndInvokeJS(Int64 taskId, Boolean succeeded, Utf8JsonReader& jsonReader)
--- End of inner exception stack trace ---
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
Is it simply "don't do this" kind of things or this should actually be fixed?
Expected Behavior
No response
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
7.0.400
Anything else?
No response