6

私は(/待つ非同期を使用して)非同期で読み取るNetworkStreamを有する非同期ソケットの読み込み:開始スレッドは終了してはいけません。

await Task<int>.Factory.FromAsync((cb, state) => stream.BeginRead(buffer, offset, readLen - offset), stream.EndRead, null); 

残念ながら、IO例外が時々発生:「I/O動作があるため、スレッドの終了またはアプリケーションの要求によって中止されています"

Socke.EndReceive:http://msdn.microsoft.com/en-us/library/w7wtt64b.aspxに記載されている要件を満たしていると思います。

特定のスレッドによって開始されたすべての入出力は、そのスレッド が終了すると取り消されます。処理が完了する前にスレッドが を終了すると、保留中の非同期操作が失敗する可能性があります。

asyncメソッドはデフォルトスケジューラで実行されるため、この要件は保証されません。

方法はありますか? I/Oを開始するために専用のスレッドを開始する必要がありますか?

よろしく、ディルク

+0

async I/Oに当てはまるのは確実ですか? Mindtouch DReAMでは何年もの間ネットワークストリームのBegin/Endを使用してきましたが、開始スレッドを常にスレッドプールに戻しています。 –

+0

こんにちはアルネ。アンマネージドスレッドを解放するのと同じではありません。私が理解しているように、その振る舞いは "ヘルプ"として意味されています。スレッドが終了すると、そのスレッドに関連するすべての作業が取り消されます。 しかし、私は自分のマシンでそれを再現することができません。これは、何百ものテストが実行されるビルドサーバー、スレッドの開始/停止、およびappdomainsの作成とアンロードが高速で連続して行われます。私が見るSocketExceptionは、EndReceiveでSocketError.OperationAbortedです。 –

+0

私はそのページを誤読したように見えます。これは、非同期のポイントが開始スレッドについて心配する必要がないため、実際は不幸な動作です。 –

答えて

-1

あなたは本の中で最古のトリックを使用することができます。あなたのスレッドは決して終わりのないループで眠れないようにしてください。

while(true) { 
    Threading.Sleep(TimeSpan.FromSeconds(1); 
} 

私は上記のコードを私の頭から書いています。私は現在Macで作業しているので、Visual Studioでチェックしなかった。

スレッドを終了するには何かを書く必要がありますが、それはアプリケーションの流れに依存します。

+2

もしあなたがなぜ非同期APIを使用するのですか? – CodesInChaos

1

終了しない専用I/Oスレッドを使用することをお勧めします。これが現実世界のコードの多くです。

スレッドループをGetQueuedCompletionStatusにするのが最も良い方法の1つです。 I/Oスレッドの1つにI/O操作を実行させる必要がある場合は、PostQueuedCompletionStatusまたはQueueUserAPCのいずれかを呼び出して、I/Oスレッドが操作をポストするようにします。

注意:これらの操作が失敗するケースを処理する必要があります。たとえば、あまりにも多くのAPCがすでにキューに入れられている場合は、QueueUserAPCが失敗する可能性があります。

関連する問題