7

I have been trying to read data from the Twitter stream API using C#, and since sometimes the API will return no data, and I am looking for a near-realtime response, I have been hesitant to use a buffer length of more than 1 byte on the reader in case the stream doesn't return any more data for the next day or two.

I have been using the following line:

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

Now that I plan to scale the application up, I think a size of 1 will result in a lot of CPU usage, and want to increase that number, but I still don't want the stream to just block. Is it possible to get the stream to return if no more bytes are read in the next 5 seconds or something similar?

1 Answer 1

4

Async Option

You can use a timer in the async callback method to complete the operation if no bytes are received for e.g. 5 seconds. Reset the timer every time bytes are received. Start it before BeginRead.

Sync Option

Alternatively, you can use the ReceiveTimeout property of the underlying socket to establish a maximum time to wait before completing the read. You can use a larger buffer and set the timeout to e.g. 5 seconds.

From the MSDN documentation that property only applies to a synchronous read. You could perform a synchronous read on a separate thread.

UPDATE

Here's rough, untested code pieced together from a similar problem. It will probably not run (or be bug-free) as-is, but should give you the idea:

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();
}
Sign up to request clarification or add additional context in comments.

4 Comments

I can't just keep opening and closing the connection because of Twitter's policies. Can you give an example of how I could use the async callback timer to terminate the read early?
@huadianz: Added a rough example to give you a starting point.
Does the Read return any data in the buffer, or is that data lost?
@huadianz: The buffer should contain any data you have read so far, even if the read was aborted after 5 seconds.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.