2012-12-12 8 views
7

Próbowałem odczytać dane z API strumienia Twittera za pomocą C#, a ponieważ czasami API nie zwróci żadnych danych, a ja szukam odpowiedzi w czasie zbliżonym do rzeczywistego, Byłem niezdecydowany, aby użyć na swoim czytniku długości bufora większej niż 1 bajt, na wypadek gdyby strumień nie zwrócił więcej danych na następny dzień lub dwa.Zużywając strumień HTTP bez czytania jednego bajtu na raz

Używam następujący wiersz:

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

Teraz mam zamiar skalowanie aplikacji w górę, myślę, że rozmiar 1 spowoduje dużo użycie procesora i chcą zwiększyć tę liczbę , ale nadal nie chcę, aby strumień blokował się. Czy możliwe jest przywrócenie strumienia, jeśli w ciągu następnych 5 sekund nie zostanie odczytane więcej bajtów lub coś podobnego?

Odpowiedz

4

asynchroniczny Opcja

można użyć czasomierza w sposób asynchroniczny zwrotnej, aby zakończyć operację jeśli nie bajty są otrzymane na przykład 5 sekund. Zresetuj licznik za każdym razem, gdy odbierane są bajty. Uruchom go przed BeginRead.

Opcja synchronizacji

Alternatywnie, można użyć właściwości ReceiveTimeout z gniazdka bazowego ustalić maksymalny czas oczekiwania przed zakończeniem lektury. Możesz użyć większego bufora i ustawić limit czasu na np. 5 sekund.

Ta właściwość dotyczy tylko odczytu synchronicznego z MSDN documentation. Możesz wykonać synchroniczny odczyt w oddzielnym wątku.

UPDATE

Oto szorstki, niesprawdzone kod poskładane z podobnym problemem. To prawdopodobnie nie będzie działać (lub będzie wolna od błędów) jak jest, ale powinno dać wam pomysł:

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

Nie mogę utrzymać otwieranie i zamykanie połączenia, ponieważ polityk Twittera. Czy możesz podać przykład wykorzystania asynchronicznego zegara wywołania zwrotnego do wcześniejszego zakończenia odczytu? – HenryZhang

+0

@huadianz: Dodano przybliżony przykład, aby dać ci punkt wyjścia. –

+0

Czy funkcja Read zwraca jakiekolwiek dane w buforze, czy te dane zostały utracone? – HenryZhang

Powiązane problemy