System.Threading.Thread.Abort()の処理を実装したいと考えております。
現在、開発中のシステムでは、C#でからsshでLinuxへ接続して、
過去に開発された、コンソール画面でGUIっぽく見せたシステムを操作させています。
通常のsshのレスポンスと異なる点は、
System.IO.Stream.ReadByte()でレスポンスを受け取る際に既にすべて受信していると、
C#側ではレスポンス待ちのままフリーズしてしまいます。
System.IO.Stream.Readでも、レスポンス以上のバイトを取得しようとすると同様にフリーズしてしまいます。
ここの回避策としては、リクエストごとに想定されるレスポンスメッセージパターンを作成し
必要分取得したらReadByte()を呼ばない様な対応をしてきました。
今回、System.Threading.Thread.Abort()が必要になったのは、
想定されるパターンが多すぎて、網羅しきれない場合を考慮し、
フリーズ発生時にAbortをかけようとしています。
ですが、残念ながら.NET coreでは、上記機能をサポート対象から外してしまったそうで、
代わりに、CancellationTokenが利用できる非同期処理を呼び出すようにしている様です。
Thread.Abort()だと同じ行でフリーズしてしまうため、CancellationTokenを指示しても、
処理を抜けることが出来ない状態となっております。
.NET CoreでもThread.Abort()を呼び出す方法があるのでしょうか?
他にも回避策があれば、教えていただきたいです。
2020/06/06追記
説明が不足しており申し訳ございません。
想定されるパターンが多すぎて
想定されるパターンは、入力に対するレスポンスのパターンです。
イメージとしてはTeratermでssh接続し、Linux側のアプリケーションを起動すると指定の行・列情報や文字色などのルールをバイト単位で返却して画面描画を行っています。
利用者は、全てキーボードでメニュー選択などを行い対話することが可能です。
このアプリケーションの問題点は、レスポンスが終わったときにレスポンス完了した旨がわかるバイトコードを返さないという点です。
ssh接続を行いlsコマンドを受け取ったりする際においては、読取処理でフリーズすることはないかと思います。
上記のアプリでは、最後のバイトコードが普通に画面表示を行うための文字を返している可能性もあり得ます。
例えば、http/2のプロトコルにおいて、レスポンスを返す際は、レスポンス単位にフレームがついて返却されるため、
レスポンスのメッセージだけでなく付随する情報があるかと思います。
それらのフレームの規格が全くない状態のため、メッセージを返却し終わったかどうかのルール作れないです。
CancellationTokenパターンで以下の様に試してみた。
このパターンだと、フリーズ発生前にcts.Cancel()を呼び出すとExceptionを発生させてくれて動作を止めることを確認しました。
しかし、上記のメッセージを返却し終わった後に、cts.Cancel()を呼び出してもExceptionは発生せず、
レスポンスを受け取ろうとするとそこで止まってしまいます。
トークンソースの作成
CancellationTokenSource cts = new CancellationTokenSource();
Task内でReadAsyncにセット
var result = await stream.ReadAsync(buffer, 0, buffer.Length, cts.Token);
キャンセル呼び出し
cts.Cancel();
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。