7

C# を使用して Twitter ストリーム API からデータを読み取ろうとしてきましたが、API がデータを返さない場合があり、ほぼリアルタイムの応答を探しているため、1 バイトを超えるバッファー長を使用することをためらっていました。ストリームが翌日または 2 日以上データを返さない場合に備えて、リーダーで。

私は次の行を使用しています:

input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null); 
//buffer = new byte[1]

アプリケーションのスケールアップを計画しているので、サイズを 1 にすると CPU 使用率が高くなり、その数を増やしたいと考えていますが、それでもストリームが単にブロックされることは望ましくありません。次の 5 秒などでバイトが読み取られない場合、ストリームを返すことは可能ですか?

4

1 に答える 1

4

非同期オプション

非同期コールバック メソッドでタイマーを使用して、たとえば 5 秒間バイトが受信されない場合に操作を完了することができます。バイトを受信するたびにタイマーをリセットします。BeginRead の前に開始します。

同期オプション

または、基になるソケットの ReceiveTimeout プロパティを使用して、読み取りが完了するまでの最大待機時間を設定できます。より大きなバッファを使用して、タイムアウトを 5 秒などに設定できます。

プロパティが同期読み取りにのみ適用されるMSDN ドキュメントから。別のスレッドで同期読み取りを実行できます。

アップデート

これは、同様の問題からまとめられた、テストされていない大まかなコードです。おそらくそのままでは実行されません(またはバグがありません)が、アイデアが得られるはずです。

private EventWaitHandle asyncWait = new ManualResetEvent(false);
private Timer abortTimer = null;
private bool success = false;

public void ReadFromTwitter()
{
    abortTimer = new Timer(AbortTwitter, null, 50000, System.Threading.Timeout.Infinite);

    asyncWait.Reset();
    input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null);
    asyncWait.WaitOne();            
}

void AbortTwitter(object state)
{
    success = false; // Redundant but explicit for clarity
    asyncWait.Set();
}

void InputReadComplete()
{
    // Disable the timer:
    abortTimer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
    success = true;
    asyncWait.Set();
}
于 2012-12-12T00:09:53.307 に答える