C#をWASMにしてWebアプリにしたい
自作した乱数調整ライブラリの資産がそこそこ多くてJS/TS移植するのが大変なのと、そもそも整数型を持たないJSで擬似乱数ライブラリを書くのがつらいということで、WASMでえいえいできないか調べた
最初はBlazorWASMを使っていた
WASMだと流石に検索処理が重くて、A0~A31の5V個体の検索だけでも数秒かかる
そこで検索処理をWebWorkerに逃がそうとした
C#側で書いたasyncに対応するのはJS的なasync(非同期)であってマルチスレッドにはならないので、I/O待ちではない純粋な重い処理を逃がす用途にasyncは使えない
C# WASMからWebWorkerを使うライブラリはあったのだが、試した時点ではWorkerにプリミティブ型しか渡せないというめちゃくちゃでかい欠陥があった その後機能追加があったらしいがまだ触っていない
後述する理由からBlazorに拘る意味が薄いことに気付いた(というかできれば使いたくない)のでこちらは塩漬け
ここまでやったところで、「どうせWebWorkerに逃がすのであればC#+WASMなコードはWorkerに閉じ込めてしまって、Webアプリ部分は普通のReactとかにすればいいのでは?」と思った
C#で書きたいのはロジック部分であって、Blazorの開発体験自体はそこまで高くなかった…というか10年前のReactを書かされているような気分だった
これについてはNot for meだったという話なんだと思う。
普通のC#開発者が持っているGUIパラダイムからの飛躍が大きくならないようにするというのも1つの価値なんだなぁという話。たぶん。
Blazor抜きでWASM化だけする話もいくつか見つかった
日本語記事
リファレンス
日本語記事はいずれも「JS側を最小限にしてなるべくC#に寄せる」という方向性で、C#資産をJSで使う話ではなかったので、C#のオブジェクトをJSにExportする話を深掘りする必要があった
何らかの属性を付与したクラスを定義しておけば(JSONシリアライズみたいな感じで)それをJS側からはJSのオブジェクトとして扱える…みたいなのがほしかった
見つけた
要約すると、現時点では明示的/手動でシリアル化と逆シリアル化を行う必要があります。この問題は、オブジェクトが自動的にシリアル化 (およびできれば逆シリアル化) されるJSType.Json type の導入を提案しています。
「C#構造体とJS構造体を相互運用できるようにならない?」というIssue
「期待するほど速くはならない、おそらくJSONを介する方法よりも遅い」「RustでもJSONを経由している」という回答
JSONを経由して渡すときのボイラープレートが多いから便利にしてくれる属性がほしいな~というIssue
あれば嬉しいな
JSObject型はC#側で生成することができないっぽい
そもそもハイコストなので気軽に作る物でもなさそう…
めもとか
急にMainメソッドが無いとか言われた
トップレベルのコードを全部消したからエントリポイントが自動生成されなくなったのが原因だった。
return 0を置いてやれば解決した。
急に動かなくなった
Missing window to the query parameters fromエラーが出る
直らん
詰んだ
おそらくWASM用のバイナリ類に対してバンドルしようとしてしまっているせい
Webpackなら/* webpackIgnore: true */が必要
Viteなので/* @vite-ignore */にしたら解決した
ただしトップレベルで動的インポートしたらダメだった
関数内なら期待通りに動いた
動いたしvite-ignoreも書いてあるのにコンソールには警告が出る…
追っかける用
もしかしてWebWorkerから呼び出せない…?
できてる
viteを使うと解析を抑制する必要がある
型が欲しい…
現状
ある程度動くようになった