2012-12-12 8 views
7

Ich habe versucht, Daten aus der Twitter-Stream-API mit C# zu lesen, und da die API manchmal keine Daten zurückgibt, suche ich nach einer nahezu echtzeitfähigen Antwort. Ich habe gezögert, eine Pufferlänge von mehr als 1 Byte auf dem Lesegerät zu verwenden, falls der Datenstrom für die nächsten ein oder zwei Tage keine Daten mehr liefert.Einen HTTP-Stream konsumieren, ohne jeweils ein Byte zu lesen

Ich habe mit der folgenden Zeile:

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

Nun, da ich plane, um die Anwendung zu vergrößern, glaube ich eine Größe von 1 in einer Menge von CPU-Auslastung führen wird, und will diese Zahl erhöhen , aber ich möchte immer noch nicht, dass der Stream blockiert. Ist es möglich, den Stream zurückzugeben, wenn in den nächsten 5 Sekunden oder ähnlichem keine Bytes mehr gelesen werden?

Antwort

4

Async Option

einen Timer in der Async Callback-Methode verwenden, um den Vorgang zu beenden, wenn kein Bytes für beispielsweise empfangen werden, 5 Sekunden. Setzen Sie den Timer jedes Mal zurück, wenn Bytes empfangen werden. Starte es vor BeginRead.

Sync Option

Alternativ können Sie die ReceiveTimeout Eigenschaft des zugrunde liegenden Socket verwenden, um eine maximale Zeit einzurichten, um die Lese zu warten, bevor sie abgeschlossen ist. Sie können einen größeren Puffer verwenden und das Zeitlimit auf z. 5 Sekunden.

Von der MSDN documentation diese Eigenschaft gilt nur für einen synchronen Lesevorgang. Sie können einen synchronen Lesevorgang in einem separaten Thread durchführen.

UPDATE

Hier ist rau, pieced ungetesteter Code zusammen aus einem ähnlichen Problem. Es wird wahrscheinlich nicht ausgeführt werden (oder fehlerfrei sein), wie es ist, aber sollte Ihnen die Idee geben:

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(); 
} 
+0

Ich kann nicht immer öffnen und schließen Sie die Verbindung wegen Twitter-Richtlinien. Können Sie ein Beispiel geben, wie ich den asynchronen Rückruf-Timer verwenden könnte, um den Lesevorgang vorzeitig zu beenden? – HenryZhang

+0

@huadianz: Ein grobes Beispiel hinzugefügt, um Ihnen einen Startpunkt zu geben. –

+0

Gibt der Read irgendwelche Daten im Puffer zurück, oder sind diese Daten verloren? – HenryZhang

Verwandte Themen