Hello Everyone,
I am connecting to a server which sends updates about financial information. The code I post below will work correctly for a few minutes then usually blows up when it tries to do an EndRead (where I have noted), because there was 0 bytes at that moment to be read. Obviously in the financial world some things can stay the same price for a few minutes or more which seems to be the source of my problem. Also I suspect there is a better way to do this than what I am showing below. If you have a more efficient or elegant way to achieve the same result I am all ears. Basically the code I have now is assembled from random snippets of code from here and elsewhere. I just can't seem to find a sample that puts all the pieces together the way I need them.
Thanks in advance,
Bob
Edit: I should have clarified that I basically understand what is going wrong, I just can't find the reason why the stream is being closed. I think the best answer will be a different implementation that does the same thing. I tried making WebClient do this but didn't have any luck with that.
public IAsyncResult BeginStreamingData()
{
postUrl = "https://" + "myfinancialbytestreamsource.com/";
byte[] buffer = Encoding.ASCII.GetBytes(postdata);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(postUrl);
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip;
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.ContentLength = buffer.Length;
httpWebRequest.Timeout = 6000000;
httpWebRequest.ReadWriteTimeout = 6000000;
Stream PostData = httpWebRequest.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
IAsyncResult result =
(IAsyncResult)httpWebRequest.BeginGetResponse(new AsyncCallback(ResponseCallback), new AsyncState
{
request = httpWebRequest
});
return new CompletedAsyncResult<string>("Completed stream.");
}
internal void ResponseCallback(IAsyncResult asynchronousResult)
{
AsyncState state = asynchronousResult.AsyncState as AsyncState;
HttpWebRequest httpWebRequest = state.request;
state.response = (HttpWebResponse)httpWebRequest.EndGetResponse(asynchronousResult);
Stream responseStream = state.response.GetResponseStream();
byte[] buffer = new byte[1024 * 10];
var completedEvent = new ManualResetEvent(false);
responseStream.BeginRead(buffer, 0, buffer.Length,
AsyncRead,
new AsyncState
{
b = buffer,
s = responseStream,
e = completedEvent
});
completedEvent.WaitOne();
}
private void AsyncRead(IAsyncResult ar)
{
AsyncState state = ar.AsyncState as AsyncState;
int read = 0;
//BLOWS UP HERE (IOException) WHEN IT ENDS A READ THAT HAD 0 BYTES IN IT.
read = state.s.EndRead(ar);
if (read == 0)
{
// signal completion
state.e.Set();
return;
}
else
{
//this is where I'm parsing the bytes into .net objects.
ParseBytes(state.b, read);
}
// read again
state.s.BeginRead(state.b, 0, state.b.Length, AsyncRead, state);
}
//Here is the class that stores the state.
private class AsyncState
{
public Stream s;
public ManualResetEvent e;
public byte[] b;
public HttpWebRequest request;
public HttpWebResponse response;
}