|
I am wondering if you even read my question completely in the message. I am already returning true or false value from a function. But I want to know how could i pass a detailed error message if function crashes rather than a false value.
|
|
|
|
|
Return as Int value. Examples:
0 - Success
1 - Invalid User name/Password
2 - Can not connect to database
PS: Returning as Enum can be a little easier
PPS: You can create a Struct that has Error Code, and a message. This way you can handle error by its Code and if user needs a info, you could show the message part. There are a lot of ways to achieve this
modified on Friday, November 20, 2009 12:46 PM
|
|
|
|
|
Is this way big applications deal with complicated applications issues?
|
|
|
|
|
Some WinAPI calls handles errors with either int value or has GetLastError(). I have tried MySQL connector.NET and they have tons of errors. In their way they returned a custom Exception. That exception includes ErrorCode and a Message
This is how Microsoft uses:
System Error Codes[^]
netJP12L wrote: Is this way big applications deal with complicated applications issues?
Not sure, but this approach I saw in C++ coding style
I Suggest you chose one and stick with it. If you choose returning as Int, Make sure you are documenting every error code and maybe even using constant
|
|
|
|
|
If you re-throw the exception, then you can provide all the details you might need, and just have it return false. Alternatively, raise an event with the exception details, and know that if you return false you need to check a variable with the reason for failure.
|
|
|
|
|
You could also create a custom 'Status' enum that contains a number of different return values, for example...
public enum ReturnStatus{
True,
False,
Maybe,
CriticalError,
AcceptableError
}
then you function...
public ReturnStatus Func1(string s)
{
if(s == null)
return ReturnStatus.False;
if(s == "?")
return ReturnStatus.Maybe;
return ReturnStatus.True;
}
Life goes very fast. Tomorrow, today is already yesterday.
|
|
|
|
|
I got an another idea that i am sure you would have thought about it. How about if i were to return an object from every function. This way if the aspx page needs to show what were the exception they can easily show the acutal exception or a custom message. What do you guys think of this idea.
public Object AddUser(string username)
{
CustomObject obj = null;
try
{
obj = CustomObject(false,"",,"")
}
catch(Exception ex)
{
obj = CustomObject(true,"101",ex,"Database couldn't be started.")
}
return obj;
}
public class CustomObject
{
public CustomObject(bool errorFound, string ErrorID, Exception exception, string CustomErrorMessage)
{
}
}
|
|
|
|
|
.NET already has default mechanisms in place that let you write your web methods as if they were not, so you can have void methods and return your own custom types - although obviously the client will get just data, not operations, since it's a web service, and you do not have type affinity (the representation of the type on the client need not be the same, so you can't do things like return int and assume that the bits in the int are the same on the client side - though the number it represents will still be the same).
So how about
public void AddUser(string username)
public void DeleteUser(string userID)
public User GetUser(string userID)
public void DeleteFile(string fileID)
instead? The service will still return something indicating the call was successful for the void methods, and a serialized User object from the GetUser function. (How something like "GetUser" can be of any use returning bool is beyond me.)
As for errors, by default the exception message will be serialized and sent to the client in the event of an unhandled exception in your web service.
|
|
|
|
|
Hi there, this is - I think - my third post on this subject, which means I was still not able to implement my proxy server.
For the people that did not read my other posts, I am trying to use the .NET framework to create a proxy server that intercepts all requests to a certain port and redirects them to an indicated address (indicates by me), appending all the correct credentials (and the purpose of all this thing is to handle the authentication, so that the clients dont need to worry about it). I created a class to implement the server, and I call it like this, inside a thread.
m_prx = new ProxyServer(this);
System.Threading.Thread proxythread = new System.Threading.Thread(new ThreadStart(m_prx.Start));
proxythread.Start();
Inside the Start() method, I need to have some sort of listener, waiting for connections; on a first approach, I used a high level implementation that relies on httplistener class:
m_listener.Start();
System.Diagnostics.Debug.WriteLine("Listening socket on port " + m_port);
while (true)
{
HttpListenerContext request = m_listener.GetContext();
ThreadPool.QueueUserWorkItem(ProcessRequest, request);
This relies on the threadPool, which means .NET handles the multithreading at OS level;
The function Process Request is, in the essence quite simple: it issues a webrequest (actually httpWebrequest) and appends all the stuff (credentials, headers, etc); then,
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
request.Credentials = AddCache(uri);
request.ClientCertificates.Add(SisService.GetClientCertificate());
Then, it grabbs the stream:
buffer = new byte[BUFFER_SIZE];
Stream instream = context.Request.InputStream;
int incount = instream.Read(buffer, 0, buffer.Length);
while (incount > 0)
{
request.GetRequestStream().Write(buffer, 0, incount);
incount = instream.Read(buffer, 0, buffer.Length);
}
WebResponse response = request.GetResponse();
and it transfers it into the response:
buffer = new byte[BUFFER_SIZE];
Stream outstream = response.GetResponseStream();
int outcount = outstream.Read(buffer, 0, buffer.Length);
while (outcount > 0)
{
context.Response.OutputStream.Write(buffer, 0, outcount);
outcount = outstream.Read(buffer, 0, buffer.Length);
}
instream.Close();
outstream.Close();
context.Response.OutputStream.Close();
There is some missing code here, but this is pretty much the general idea.
It works pretty well, and it is quite fast. However, sometimes (and I believe it is when there are sycnhronous or almost syncrhonous requests from clients) it ends up in this situation (exception):
A first chance exception of type 'System.Net.HttpListenerException' occurred in System.dll
An operation was attempted on a nonexistent network connection
I thought it could be a problem with the server, so I tested it with a different server but no luck: same error, when multiple requests were thrown almost at the same time.
(I also thought the firewall might be intercepting something here, so I disabled it but it also did not have any influence).
So I guess the problem would be with my code...
My perspective was that the httplistener class was not really tackling the multithreading, which I need to have working properly because of the simultaneous requests from clients...
After this, I tried different implementations:
- an asynchronous GetContext (beginGetContext)
- implementation with real sockets: TCPListener and finally raw sockets;
The implementation with sockets is more or less like this:
TcpListener listener = new TcpListener(IPAddress.Any, m_port);
listener.Start();
DoBeginAcceptSocket(listener);
(I also use a ManualResetEvent here to send signals about the threads)
Then the callback:
public static void DoBeginAcceptSocket(TcpListener listener)
{
tcpClientConnected.Reset();
listener.BeginAcceptSocket(
new AsyncCallback(ProcessSocket), listener);
tcpClientConnected.WaitOne();
}
And the callback "ProcessSocket", is a bit similar to "ProcessRequest", except that is a bit more complex; In the end, since we are not inside a while loop, I need to call DoBeginAcceptSocket again;
This approach, also did not got me out of the problem... now I get a different error, which I think is related to the same issue (except is a different class of exception):
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
An existing connection was forcibly closed by the remote host.
(I also tried a version with the sinchronous "AcceptSocket", with the same results);
I am runnning a bit out of ideas here, about what may be the problem... has anyone incurred into this before? I would really appreciate any tips/suggestions on this that could put me into the right direction...
I have to add that I am able to catch this error and carry on (even if I have to restart the listener) and in many cases is not a problem (apart from that the user does not see some output cause the requests didnt went trought...) however... not happy about this!
Thanks in advance and have a good weekend!
Jo
|
|
|
|
|
Why do you read from the outstream???
buffer = new byte[BUFFER_SIZE];
Stream outstream = response.GetResponseStream();
int outcount = outstream.Read(buffer, 0, buffer.Length);
while (outcount > 0)
{
context.Response.OutputStream.Write(buffer, 0, outcount);
outcount = outstream.Read(buffer, 0, buffer.Length);
}
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).
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.
In the thread, you read all and send all.
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.
|
|
|
|
|
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;
|
|
|
|
|