|
Thanks a lot for the reply Paulo!!
Paulo Zemek wrote: I think you should read from instream and write to outstream.
Maybe that's the problem (I am not sure, as I don't have the full source).
I think my names are perhaps not very clear, but I am reading from the WebResponse and writing to the HttpListenerContext.Response (which is carried to the callback)
Stream instream = response.GetResponseStream();
Stream outstream = context.Response.OutputStream;
int outcount = instream.Read(buffer, 0, buffer.Length);
while (outcount > 0)
{
outstream.Write(buffer, 0, outcount);
outcount = instream.Read(buffer, 0, buffer.Length);
}
instream.Close();
outstream.Close();
Paulo Zemek wrote: Also, I think the best pattern is:
Create a TcpListener.
Start it.
In a loop, you accept a TcpClient, start a thread to process the client and continues in the loop accepting new requests.
I think I might have tried that approach: do you mean something like this?
TcpListener listener = new TcpListener(IPAddress.Any, m_port);
listener.Start();
while (true)
{
Socket client = listener.AcceptSocket();
ThreadPool.QueueUserWorkItem(ProcessSocket, client);
}
(Of course the socket client, could be a TcpListener client, but I'm not sure that makes much difference. This code is also getting into the "Stream closed exception").
Paulo Zemek wrote: And, finally, maybe the connection is lost in the middle. This can happen (think about the stop button, for example). So, if the connection is closed, it's ok. Ignore this exception.
I just dont understand why the connection is closed! Is it getting a timeout for some reason? and why is it only happening when I have multiple requests?
(I have to add I am connecting to my server and I know by a fact that no one is accessing it and the connection is not closed, because I tested it)
|
|
|
|
|
Well, in this case, I must say the problem is really the ThreadPool.
I have created a class named UnlimitedThreadPool, that acts as a ThreadPool only in the sense of reutilizing existing thread, but without limited number of threads (as happens with custom ThreadPool).
If you want you can get that class from my articles (it is in Pfz.dll) but if you don't want that, simple use real threads.
Probably, what's happening is this:
The server gets 20 requests.
ThreadPool process only 4 at a time (for example). After that 4 requests being processed, it can start processing another 4 requests but, at that time, more 20 connections where opened.
So, it has 32 requests waiting, and is processing only 4.
When if finally starts to process the request of number 30, it has already timed-out.
|
|
|
|
|
Hi Jo,
we've had this conversation before, and I still am convinced using ThreadPool for such things is wrong; the operative word in ThreadPool.QueueUserWorkItem(ProcessRequest, request); is Queue , which means you will typically get fewer threads working for you than there are requests, hence some requests will fail.
So I suggest you forget about TP and add 2 or 3 lines of code to use real Threads instead.
Luc Pattyn [Forum Guidelines] [My Articles]
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
modified on Friday, November 20, 2009 2:03 PM
|
|
|
|
|
Thanks a lot for the reply!
I refactored the code in order to wrapp my listener inside a class, which I now call insde a thread. My entry point for the proxy class, now looks like this:
m_listener.Start();
System.Diagnostics.Debug.WriteLine("Listening socket on port " + m_port);
ThreadedListener tl=new ThreadedListener(m_listener, m_service);
Thread newThread = new Thread(new ThreadStart(tl.Process));
newThread.Start();
Console.WriteLine("(0): Creathed Thread (ID {1})",
Thread.CurrentThread.ManagedThreadId, newThread.ManagedThreadId);
And this is the ThreadListener class; the method activated by the thread (process) is introducing an asynchronous callback to process the client request;
internal class ThreadedListener
{
private HttpListener m_listener;
private SisService m_service;
const int BUFFER_SIZE = 1024;
public ThreadedListener(HttpListener listener, SisService service) { m_listener = listener; m_service = service; }
public void Process()
{
HttpListenerContext request=m_listener.GetContext();
IAsyncResult result = m_listener.BeginGetContext(new AsyncCallback(RequestHandler), m_listener);
}
private void RequestHandler(IAsyncResult ar)
{
HttpListenerContext httpContext = null;
try
{
HttpListener listener = (HttpListener)ar.AsyncState;
httpContext = listener.EndGetContext(ar);
listener.BeginGetContext(RequestHandler, listener);
ResponseHandler(httpContext);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
if (httpContext != null)
{
httpContext.Response.Close();
}
}
}
private void ResponseHandler(HttpListenerContext context)
{
}
}
And guess what? I still get the same (annoying) exception at the same circunstances:
A first chance exception of type 'System.Net.HttpListenerException' occurred in System.dll
An operation was attempted on a nonexistent network connection
I did also a small change, to take the proxy class outside the thread; It was previously like this in my main method:
System.Threading.Thread proxythread = new System.Threading.Thread(new ThreadStart(m_prx.Start));
proxythread.Start();
And is now like this:
m_prx = new ProxyServer(this);
m_prx.Start();
(I thought we dont need another thread here; but Im not sure this has any influence; probably not)
Any ideas?
Thanks again for helping me with this,
Jo
|
|
|
|
|
i just have a thought that perhaps I should not use asynchronous calls (which is threaded at OS level) with explicit threading... I am gonna reconsider that.
J
|
|
|
|
|
Hi Joana,
I find your code hard to follow.
For one, you have:
ThreadedListener tl=new ThreadedListener(m_listener, m_service);
Thread newThread = new Thread(new ThreadStart(tl.Process));
newThread.Start();
Now if ThreadedListener really was a threaded-something, it would take care of threading inside itself. The way it is now, it'd rather be called ListenerToBeCalledOnAThread.
Also, I see
HttpListenerContext request=m_listener.GetContext();
IAsyncResult result = m_listener.BeginGetContext(new AsyncCallback(RequestHandler), m_listener);
That is two GetContext calls, one synchronous, one asynchronous. Now why two? and why is the second one asynchronous? The whole idea of using threads is to avoid asynchronous operations, I can't remember any circumstance that made me mix both threads and asynchronous operations.
Finally, for the exception you mention, you don't provide much detail. Where does it occur? did you look at its ToString() value rather than its Message? does your IDE show line numbers[^]? do you have all required try-catch blocks?
Luc Pattyn [Forum Guidelines] [My Articles]
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
Thanks again for the observations! There were two major issues with my approach (as you pointed):
- There is no need for asynchronous calls in the threaded implementation;
- To prevent my problem, I need to move the ProcessRequest function to threads, rather than the listening (the listening needs to be inside a thread as well, but just for the sake of not blocking the main thread, with the UI).
Having that in mind, I rewrote the Start method of the ProxyServer to look like this:
m_listener.Start();
System.Diagnostics.Debug.WriteLine("Listening socket on port " + m_port);
ThreadedListener tl = new ThreadedListener(m_listener, m_service);
Thread newThread = new Thread(new ThreadStart(tl.Process));
newThread.Start();
The listener class is now inside a thread; the Process function, refered by ThreadStart is sitting on a loop, waiting for the request; and inside this loop one thread is instantiating for each processRequest call (n.b.: this is the critical piece of code, where I actually handle the request and send it to the client and is also where the exception is thrown).
while (true)
{
HttpListenerContext request = m_listener.GetContext();
req myReq=new req(m_service);
Thread newThread = new Thread(myReq.ProcessRequest);
newThread.Start(request);
}
In a very empirical analysis, the application seems to me faster and encountering less exceptions... however I still enter the httpListenerException once in a while; This is the msdn error code:
ERROR_CONNECTION_ACTIVE
1230 (0x4CE)
And this is the description of the exception:
An invalid operation was attempted on an active network connection.
I am catching it, so in most cases is actually fine; however, the reason why I am so worried is that sometimes I am working with SSL authentication, in which case the SSL related classes send some exceptions that I cannot catch and cause my app to malfunction and eventually crash (maybe I will have to work on that problem, if I cannot solve this exception problem);
Thanks a lot,
cheers,
Jo
|
|
|
|
|
And maybe I can add that what is throwing this exception [1229] is exactly this line of code, that is trying to write data in the context.Response.OutputStream;
outstream.Write(buffer, 0, outcount);
I checked the outstream variable, and it seems ok: property CanWrite is true and closed is false; No idea what's going wrong here
cheers,
Jo
|
|
|
|
|
If this is happening a lot there probably is some sort of issue with the code, but it does seem a bit odd. If there is any event available on the stream when it's state changes you could try to subscribe to the event and dump the thread ID and Environment.StackTrace to debug output (or a file or whatever); that might provide some clues perhaps. (If there is no such event you may be able to achieve the same by writing a stream class that wraps the real stream - at least it'll be easy to identify anything that explicitly closes the stream then.)
I'm wondering how often dropped connections do occur under normal circumstances. My browser will sometimes show an error page (when my connection is particularly bad!) informing me that "the remote server closed the connection" or "stopped responding" but I don't know whether or not it retries any requests before giving up.
You could probably employ that as a strategy, to automatically retry a request say 2 times in the event of a dropped connection while obtaining the response. Just make sure you don't do it for POST requests; it would be a pity if the user's order to buy $5K of some stock resulted in buying $15K because the request was automatically retried... Come to think of it, that *could* happen with any request, it's certainly possible to perform such things based on a querystring alone; however, doing such a thing would be a clear violation of HTTP protocol guidelines!
|
|
|
|
|
I want to say Thanks to everybody who reply to me: your tips and suggestions were really helpful on tackling this issue.
As I said on previous posts, and following a lot of suggestions (Thanks Luc!) I decided to go for an implementation with explicit threading (giving up on the ThreadPool and Asynchronous webrequests, that don't seem to work well with my problem).
Apart from being much faster (cause I now take advantage of the parallelism), the application seems to throw that odd exception less often. Since I am able to catch it, and there is no real disturb for the client (it seems to render ok, despite some requests not being correctly responded) I decided to leave it as it is.
I googled a lot for this exception, and I don't seem to fidn any solution for the problem; maybe it is expected that sometimes the stream fails?
A first chance exception of type 'System.Net.HttpListenerException' occurred in System.dll
System.Net.HttpListenerException: An operation was attempted on a nonexistent network connection
at System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
AFAIK, most people seem to be swallowingthis exception. Anyway, I will close this problem here but if anybody has something new to add about this, it will be always good to know!
cheers,
Jo
|
|
|
|
|
Hi ,
This is in continuation of my previous post.
I am creating a windows application in which i query data from 5-6 tables in sql and display it in excel. My problem is:-
I also need to format my excel sheet as follows:
the data has different values in 5 columns for the same values in the first 10 columns.
I need to show the columns with same data only once and then just populate the columns which have different data for the same value in first 10 columns.
Any help or suggestions are greatly appreciated.
|
|
|
|
|
The first thing that comes to my mind is to use a template sheet that you keep filling over and over again.
I used the same thing some time ago and it worked
|
|
|
|
|
yeah , thanx that sounds good but the data i am returning is sizeable amount so if i refill several times for each to get the formatting it would be an overkill for my application. !!
|
|
|
|
|
Hi All, I am trying to get all the table name that exist in my database.
Can any body please help me.
thanks
|
|
|
|
|
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
|
|
|
|
|
hi, MeLight,
using your code I get the first talble name. how do I get the rest.
con = new SQLiteConnection(@"Data Source= mydata;Version=3;New=False;Compress=True;");<br />
con.Open();<br />
cmd = new SQLiteCommand();<br />
cmd = con.CreateCommand();<br />
cmd.Connection = con;<br />
cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name ";<br />
object tablecount = cmd.ExecuteScalar();
how do i get the rest.
thanks.
|
|
|
|
|
Don't use a scalar - that returns a single value. Use a DataReader instead.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
con.Open(); // move it below
cmd = new SQLiteCommand(); // don't need it
cmd = con.CreateCommand();
cmd.Connection = con; // don't need it
con.Open();
|
|
|
|
|
ok , let me try it and I will let you know.
|
|
|
|
|
What do you use to connect to the database?
|
|
|
|
|
Try the following...
A simple example of SQL server admin tools.
Thanks
Md. Marufuzzaman
Don't forget to click [Vote] / [Good Answer] on the post(s) that helped you.
I will not say I have failed 1000 times; I will say that I have discovered 1000 ways that can cause failure – Thomas Edison.
|
|
|
|
|
Hi,
I'm trying to generate a key press with C#, so that it can be picked up by another app. I tried to use the SendKeys class to achieve what I'm looking for
while (true)
{
SendKeys.SendWait("{F1}");
Thread.Sleep(500);
}
which works for most apps I tried (FireFox, VS2008 etc), but not the app I'm looking to control - Frets on Fire[^]. I was told that the problem might occur because FoF doesn't deal with windows messages, but instead, polls the input device (keyboard) directly.
Is there an option to simulate the behavior of an actual keyboard (write directly to the memory responsible for keyboard or something), or applying some other workaround?
Thank you!
|
|
|
|
|
MeLight wrote: Is there an option to simulate the behavior of an actual keyboard (write directly to the memory responsible for keyboard or something), or applying some other workaround?
The only thing I can think of would be to write your own keyboard driver (cannot be done in C#!) and have it generate key states on demands of an external application.
Don't ask for examples, I don't have any.
|
|
|
|
|
I think I've found the problem. FoF reacts to the sendkey events, only I believe they are too quick to have any effect. I'm trying the SendInput solution now, which is not going so well, as I lost even the functionality I've had with SendKey (im probably doing something wrong).
How would "hold down" a button programatically?
Thanx
edit: I've also tried the keybd_event() thingie (with DllImport) and it gives same results as SendKey (only sending one command on key down), the key released command seems to have no effect also.
|
|
|
|
|
Hello,
I need to migrate a COM written in C++ to C#.
Is it possible to use the same CLSID (GUID) for both?
I ask this because after i remove the C++ component, i will install the C# one and i dont wan't to change any app that are using the old component.
is it possible? or will be some conflicts?
Thanks,
F
|
|
|
|
|