20220113のC#に関する記事は4件です。

OpenGLのライブラリCsGLのexampleでNeHeの例題をコマンドラインからビルドして実行した。

始めに C#でOpenGLを扱うためにCsGLを導入して有名な例題であるNeHe のプログラムを実行してみます。 srcに付属するlesson02~lesson17まで実行してみます。 環境 Windows 11 Pro Visual Studio 2017 Express CsGL 1.1 ビルド コマンドラインでビルドします。 プラットフォームの指定 x64では動作しないのでx86を指定します /platformで指定します。 コロンで区切って記述します。 ライブラリの指定 /referenceでdllを指定します。 CsGLの場合はcsgl-opengl.dllを指定します。 コモンファイルの指定 例題によってはcommon.csを指定しないと動作しません。 エラーが出た場合はcommon.csを追加します。 エラー 例題によっては、Form top = new ScreenFormの行が動作しません。 コメントにして Form top = new Form(); に変更しました。 csc lesson02.cs /platform:x86 /reference:csgl-opengl.dll ... csc lesson05.cs common.cs /platform:x86 /reference:csgl-opengl.dll ... 結果 lesson02 lesson03 lesson04 lesson05 lesson06 lesson06b lesson07 lesson08 lesson09 lesson11 lesson17
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

OpenGLのライブラリCsGLのexampleでNeHeの例題をビルドして実行した。

始めに C#でOpenGLを扱うためにCsGLを導入して有名な例題であるNeHe のプログラムを実行してみます。 srcに付属するlesson02~lesson17まで実行してみます。 環境 Windows 11 Pro Visual Studio 2017 Express CsGL 1.1 ビルド コマンドラインでビルドします。 csc lesson02.cs /platform:x86 /reference:csgl-opengl.dll ... csc lesson05.cs common.cs /platform:x86 /reference:csgl-opengl.dll ... 結果 lesson02 lesson03 lesson04 lesson05 lesson06 lesson06b lesson07 lesson08 lesson09 lesson11 lesson17
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HostObject内でしれっと JS を書いていく

HostObject.cs public class HostObject{ protected CoreWebView2 core = null!; public HostObject(WebView2 view) { view.NavigationCompleted += (s,e)=>{ core = view.CoreWebView2; core.AddHostObjectToScript("test",this); IIFE(@$" var e = new Event('HostObjectAdded') e.value = {{ name:'exe', methods:{JsonSerializer.Serialize(GetMethods())}, }} dispatchEvent(e) "); }; } protected async void IIFE(string script){//即時実行関数式 try{ if(core!=null) { var r = await core.ExecuteScriptAsync($"(function(){{{script}}})()"); } }catch{Debug.WriteLine("x");} } public string[] GetMethods(){ var methods = new List<string>(); //... return methods.ToArray(); } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

非同期処理を含む終了処理はTaskをawaitせずにWait()で同期的に待たなければならないケースもあるよ

非同期処理を含む終了処理 特にアンマネージリソースを扱う場合において、終了処理(キャンセルを含みます)では非同期処理を行うことがよくあります。 IAsyncDisposableインターフェイスを実装するクラス System.Threading.ChannelsクラスのCompleteAsync()メソッドのような、適切なタイミングで明示的に実行する終了処理 アンマネージリソースを使って終了時のログを書き込む場合に1回だけ行うWriteAsync的な普通の非同期メソッドの実行 RDB処理が終わったときに行うトランザクションの後片付け 最近のAPIにはAsyncメソッドが標準搭載されているものも多いため、終了イベントに行うメソッドをasyncにしてawaitしたくなります。しかし、一部の終了処理ではawaitすると処理の完了を待たずに終了してしまうこともあり、ハマることがあります。 本稿ではawaitしてはいけない処理を2つ紹介します。 WinFormsのFormClosingイベントおよびFormClosedイベント WinFormsには画面を閉じるときのイベントとして以下があります。 FormClosingイベント 画面を閉じる直前に発動します。 キャンセルして閉じないことも可能です。 FormClosingイベントを抜けるまでに閉じるのをキャンセルされていなければ画面を閉じてFormClosedイベントに進みます。 FormClosedイベント 画面が閉じたあとに発動します。 もう閉じているのでキャンセルはできません。 スタートアップオブジェクトの場合、FormClosedイベントを抜けるとアプリケーションが終了します1。 イベントハンドラは当然ですがasyncにできます。asyncにして内部でawaitした場合、メソッドを一回抜けて非同期で処理を待ちます。 ・・・おわかりでしょうか?FormClosingイベントもFormClosedイベントも、メソッドを抜けた段階で次のイベントに進んでしまいます。そのため、この2つのイベントハンドラでawaitするとその行以降の処理が行われずにそのまま画面が閉じます。スタートアップオブジェクトでこれをやると、awaitしているTaskが未完了でもアプリケーションが即終了します。 このため、FormClosingおよびFormClosedでは非同期処理をawaitしてはいけません。 コンソールアプリのCancelKeyPressイベント コンソールアプリはCtrl+Cキーでアプリケーションを終了させることが可能です。このCtrl+Cキーが押されたときになにか処理をしたい場合、Console.CancelKeyPressイベントにイベントハンドラを登録できます。このイベントハンドラで終了をキャンセルすることもできます。なお、このイベントが抜けるとコンソールアプリは終了します。 ・・・もうお気づきですね?WinFormsの場合と同様に、CancelKeyPressイベントのハンドラでawaitすると完了を待たずにアプリケーションが即終了します。 まとめ 以上、2つのケースを紹介しました。私はこの他にも、ほとんどFire-And-Forgetな長命のスレッド処理(アプリケーションと寿命がほぼ同じになるように作る1個だけのスレッドループ)をCancellationToeknSourceでキャンセルする場合に、Cancel()メソッド実行後に長命スレッドのTaskをWaitすることが多いです。このようなTaskはアプリを終了させるときとかリトライで長命スレッドを即復活させるときにしかキャンセルしないため、キャンセル処理全体が同期処理になりがちなのでWaitしてOKなためです。 「TaskはWait()やResultプロパティにアクセスしてはいけない」という説明はよくありますし私も全面的に同意です。ただしそれは通常の場合であってよくわかって使うならOKです。それが適切なケースならば適切なやり方を行いましょう。ただし、急にTask.Wait()されるとぎょっとするので「終了処理のため同期的に行う」みたいなコメントがあると大変助かります。 そもそも終了時に行わなければいけない処理なら、それが完了するまで正常終了させることはできません。終了時に行う処理は同期処理として実装するかTaskが完全に終わるまでWait()で同期的に待ちましょう。複数のTaskを終了させる場合はTask.WhenAll(~~).Wait()すれば並列したうえで同期的に待てばOKです。 ただしIsCancellationRequestedでキャンセルを判定してキャンセルされていたら終了処理する、みたいな場合にその中でawaitしているとデッドロックを起こす可能性があります。初期化処理や終了時処理はセンシティブなのでよく考えてプログラミングしましょう。 正確にはエントリポイントのRunメソッドの次に行く ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む