問題タブ [beginread]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
timeout - .NET キャンセル ストリーム BeginRead
HttpWebRequest が成功した後、非同期読み取り操作をキャンセル/終了する方法を見つけることができませんでした。タイムアウトを設定する方法はありません。ThreadPool.RegisterWaitForSingleObject も機能していません。また、基になるソケットを閉じることもオプションではありません。これは、HttpWebRequest/Reponse がアクセスを提供しないためです。
編集:
悲しいことに、Sunny が提案するこのアプローチは、HttpWebRequest.BeginGetResponse に対してのみ機能します。何らかの理由で GetResponseStream() の後に取得するストリームの場合、 RegisterWaitForSingleObject が機能していません - コールバックは呼び出されません。
状況は次のとおりです。HttpGetRequest を使用するアプリケーションを入手しました。非同期 httpwebrequest の既定の MSDN の例を使用してビルドされます。応答を得ることは魅力のように機能しています。しかし、まれに、私の httpwebrequest が接続しているサーバーがソケットを閉じるのを忘れることがあります。そのため、BeginRead からの無限読み取りにかかっています。
まれに、他のサーバーが忘れる
c# - Stream.BeginRead メソッドを使用する場合、どのようにデータのソースを知ることができますか?
Stream.BeginRead メソッドを使用し、ストリームからメモリに読み取る場合、データの読み取り元はどのように決定されますか?
参照: http://msdn.microsoft.com/en-us/library/system.io.stream.beginread.aspx
パラメータのリストには、データがどこから読み取られているかを示すものはありません。
パラメーター
- buffer 型: System.Byte[] データを読み込むバッファ。
- offset 型: System.Int32 ストリームから読み取ったデータの書き込みを開始するバッファ内のバイト オフセット
- count 型: System.Int32 読み取る最大バイト数。
- callback 型: System.AsyncCallback 読み取りが完了したときに呼び出されるオプションの非同期コールバック。
- state 型: System.Object この特定の非同期読み取り要求を他の要求と区別するユーザー指定のオブジェクト。
asynchronous - BeginReceive / BeginRead タイムアウト
私は NetworkStream と TcpClient を使用して、BeginRead を使用してデータを非同期に受信しています。指定した時間が経過すると読み取りが中止されるように、この操作にタイムアウトを適用する必要があります。
私が知る限り、これは NetworkStream または TcpClient ではサポートされていません - ReceiveTimeout プロパティがありますが、これは同期に相当する「読み取り」にのみ適用されるようです。
基になる Socket クラスでさえ、その BeginReceive メソッドでタイムアウトをサポートしていないようです。
この問題について検索したところ、タイムアウト期間内に操作が完了しない場合に操作をキャンセルする別のバックグラウンド スレッドをセットアップするという唯一の解決策が提案されました。これは恐ろしいハックのようです。きっともっと良い方法がありますか?
c# - AsyncCallback関数の外部で非同期ストリームを停止する
Streamオブジェクトがあり、BeginReadを使用して(明らかに)バッファーへの読み取りを開始しています。読み取りが完了すると、AsyncCallback関数が呼び出されます。この関数内で、ユーザーが次の「ブロック」を取得して、BeginReadプロセスを再開するかどうかを確認できます。
私が抱えている問題は、ユーザーがストリームの読み取り中にキャンセルすることを選択する可能性があることです(つまり、AsyncCallback関数が呼び出される前に)。ストリームの読み取りをキャンセルするにはどうすればよいですか?
問題をさらに説明するために、StreamsReadメソッドまたは非同期BeginReadメソッドでBackgroundWorkerを使用した場合も同じ結果になるようです。ストリームの読み取りを停止する必要があるかどうかを確認する前に、Read/BeginReadメソッドが完了するまでユーザーを待機させておくことができます。
編集:以下のコードはうまくいくはずです、私はC#でまともなものから何百万マイルも離れているので、解決策を示していますが、完璧ではないと思うので、いくつかのバグがあるかもしれません。
簡単に言うと、CWorkManagerは特定の数のスレッド(CWorkerDetailクラス内に保持されている)を管理します。各CWorkerDetailにはステータスがあり、EWaitingはワーカーを開始できることを意味し、EReadingはワーカーがソースから読み取りを行っていることを意味し、その間にワーカーを即座に停止できます。EWritingは読み取られたデータをディスクに保存します-これを即座に停止することはできず、スレッドを停止する前にこのプロセスを完了する必要があります。最後に、ワーカーができるだけ早く中止する必要がある場合にマネージャーによって設定されるEAbortingがあります。現在、これは、ワーカーが中断できない何か(ディスクへの書き込みなど)の途中にある場合にのみ設定されます。
現在、読み取りや書き込みは実際には行われていません。これは、メインソリューションを複雑にするだけです(基本的には、StopWorker関数がCWorkerのフラグをチェックして、即座に中止できるかどうかを確認します)。そのため、スレッドをスリープ状態にするだけです。
GUI側は、リストボックス(各ワーカーのステータスを表示)と停止および開始ボタンだけでかなりシンプルです。すべてのコードは以下のとおりです。これが誰かに役立つことを願っていますが、私が言っているように、私はC#に精通していないので、バグなどに注意してください...
CWorkManager.cs:
Form1.cs:
含まれています:
- リストボックス(ListBox_WorkerStatus)
- ボタン(Button_Start)
- ボタン(Button_Stop)
c# - Stream.BeginRead() を停止します。
仮想 COM ポートからデータを読み取り、「Dreq」というメッセージを検出する必要があります。接続ボタンを押すと、COM8 ポートに接続され、新しいスレッドで読み取りが開始されます。また、読み取りを閉じてCOM8ポートから切断したい切断ボタンもあります。ただし、BeginRead を閉じるのに問題があります。
c# - FileStream.Beginread非同期読み取り操作を中止/キャンセルすることは可能ですか?
USBインターフェースを使用してSTM32マイクロコントローラーを制御したい。Jan Axelson(http://www.lvr.com/hidpage.htm#MyExampleCode)は、現在私のベースソースであるUSBHIDクラスの使用法を示すいくつかのアプリケーションを作成しました。
Filestream.BeginRead()
デバイスに保留中のデータがあるかどうかを確認するために、ルーチンを呼び出すスレッドを作成しました。このリクエストを中止/キャンセルしたいのは、そのスレッドを終了した後もまだ開いている/ブロックされているためです(スレッドループをキャンセルする変数を設定します)。ですから、このBeginRead()
通話をキャンセルするにはどうすればよいのでしょうか。または、USBデバイスの継続的に送信されたデータをチェックする方法についてより良いアイデアがありますか?
c# - C# Winforms と NetworkStream.BeginRead()、ネットワーク イベントに基づいて新しいフォームを開く方法は?
NetworkStream.BeginRead() と WinForms クラスの間で、あるスレッドから別のスレッドへの通信を取得する際に深刻な問題が発生しています (スレッド化や非同期呼び出しなどのトピックに関しては、私は本当に初心者です)。
特に、ネット ソケットを介してリモート クライアントに接続し、単にイベントをリッスンしています。受け取ったら、NetworkStream の BeginRead() メソッドと EndRead() メソッドを使用して文字列に正しく収集できます。問題はありません。次に、情報をユーザーに表示できるように、(フォームのコンストラクターで文字列をパラメーターとして使用して) 新しいフォームを開くつもりです。事実上、ネットワーク イベントは、ユーザーが開くフォームと情報をトリガーします。しかし、私は常に CrossThreadMessagingExceptions に出くわします。誰かが私を正しい方向に向けることができますか?
multithreading - BeginRead/EndRead の Windows CE 6.0 スレッド モデル?
Windows CE でのソケットの非同期パターン、特にソケットの BeginRead でスレッドがどのように使用されるかに関する確認またはドキュメントを探しています。MSDN のドキュメントを見てきましたが、漠然とした参照しか見つかりません。ここで検索して、デスクトップスレッドモデルへの回答を見つけました。ちなみに、このプログラムは Compact Framework で実装されています。
したがって、私の理解は次のとおりです。BeginXXX を呼び出すデスクトップでは、BeginXXX を呼び出すスレッドとは別のスレッドによってコールバックが呼び出される場合と呼び出されない場合があります。(私が読んで実験したものから ThreadPool から取得)
Windows CE では、BeginXXX を呼び出すと、BeginXXX を呼び出したスレッドによってコールバックが処理されます。
これは正確ですか?もしそうなら、どこでドキュメントを見つけることができますか? STW も RTM も役に立ちませんでした。
c# - 長さで区切られていないデータの非同期解析
私は同期Beginを使用して切り替えたネットワークサーバーを持っています..短期間のリクエストを処理するために、これは大きな改善でした. 存続期間の長いものについては、2 つのスレッドが作成され、クライアントの数が増加するにつれて問題になり始めています。
これらの接続を介して転送されるデータは、4 ~ 40 バイトのメッセージです。ただし、それらは長さで区切られておらず、その長さはメッセージ内の部分によって異なります。残念ながら、プロトコルを変更することはできません。このプロトコルは、ペースの速い telnet 端末プロトコルと考えることができます。
Stream.BeginRead を使用して受信メッセージ/「行」を読み取って解析することを検討しており、2 つの懸念事項に達しました。
- 10 バイトのメッセージに対して BeginRead を 3 回ほど呼び出すのは効率的ですか?
- これを行うコードを効率的に書くにはどうすればよいですか
ここに一例があります。メッセージ自体には長さの接頭辞が付いていませんが、その内容の一部に長さの接頭辞が付いている場合があります。
同期方式(現行)
非同期方式
非同期の例は私が使用しているものではありません。リクエストされたバイト数の読み取りが成功したかどうかをチェックするラッパーをいくつか作成しました。これは、私が取得できる記述されたコードを記述して理解するという点で効率的ですか?
私のコードは.NET 3.5で実行する必要がありますが、将来的には5がオプションになるので、それを待ってから非同期プログラミングを行う必要がありますか?
このコードはインターネットに面し、同期読み取りを使用すると、着信接続がハングするとスレッドプールスレッドがロックされます。
c# - C# ネットワーク ストリームの断片化されたデータ
私の状況
シリアル化され、base64 にエンコードされた大きなオブジェクトを接続経由で送信する TCP ネットワーク プログラムがあります。私はクライアント ライブラリとサーバー ライブラリを作成しましたが、どちらも と を使用NetworkStream's
Begin/EndRead
していBegin/EndWrite
ます。私が使用している(非常に単純化されたバージョンの)コードは次のとおりです。
サーバーの場合:
次に、クライアント:
クライアント ライブラリには、を介してデータを文字列として渡すNetworkStream.BeginRead
イベントをトリガーするコールバック メソッドがあります。OnMessageFromServer
MessageEventArgs
私の問題
ただし、を介して大量のデータを受信BeginRead/EndRead
すると、複数のメッセージに断片化されているように見えます。EG これは長いメッセージのふりをします:
それが本当に長いメッセージだった場合、Client_OnMessageFromServer
呼び出される可能性があります...「長いメッセージ」の断片化された部分で3回言ってください:
すぅぅぅぅ……深呼吸
Begin/EndWrite
への 1 回の呼び出しですべてを 1 つに送信して受信するには、どのような方法が最適でしょうClient_OnMessageFromServer
か?