singleton messagebox - c#

I am writing an application in which when something happened to the connection I want to pop up a messagebox and show the user the error...
for this purpose when the program throw an exception it will come to the catch block and in that I want to show the user the message here is the code :
catch (WebException ex)
{
if (!(ex.Message == "The operation has timed out."))
{
MessageBox.Show(ex.Message);
}
}
As it seems the program will come to this catch something like forever till the connection is become fixed so what should I do to update my message on just one messagebox at a time?

There is not much control over MessageBox when it's displayed. I would use another Form displayed in a modal mode. Before displaying, you can start a separate thread and put the logic to monitor the connection. When re-established, notify the message form and close it.

You can use something like:
public static class FailureMessagebox
{
private static bool _hasBeenSuccessful = true;
public static void ShowIfFailure(Action someAction)
{
try
{
someAction();
_hasBeenSuccessful = false;
}
catch (Exception err)
{
if (_hasBeenSuccessful)
MessageBox.Show(ex.Message);
_hasBeenSuccessful = false;
throw;
}
}
}
Sample usage:
try
{
WebResponse response;
FailureMessagebox.ShowIfFailure(() => response = webRequest.GetResponse());
}
catch (WebException err)
{
//handle the exception here.
}

Related

Send exception to Caller method in c#

Hello guys i'm working on Database assignment in this i have one windows form and one class that i use to connect database and to execute queries and non-queries.
Question: I m using Post-Message label which inform only when "Product added successfully".but when i send wrong-data which can occur exception in executeNonQuery() in database class and after catching this exception and showing Error in message box.Control goes back to caller and it prints lblPostMsg in both cases which is "Product has been added successfully".
I want that when exception occur in database class i can stop executing rest of the code or if there is way that exception in calling method can be caught by caller method.
below is Code of windows Form button
private void btnInsert_Click(object sender, EventArgs e)
{
con = new DbConnection();
con.SqlQuery("INSERT INTO products VALUES(#products_ID,#products_Name)");
con.cmd.Parameters.AddWithValue("#products_ID", txtProID.Text);
con.cmd.Parameters.AddWithValue("#products_Name", txtProName.Text);
try
{
con.ExecuteNonQueryF();
this.categoriesTableAdapter1.Fill(this.purchasemasterDS.categories);
SystemSounds.Beep.Play();
lblPostMsg.Show();
lblPostMsg.Text = "Product has been added successfully";
}
catch (Exception ex)
{
throw;
}
finally
{
con.CloseCon();
}
}
This code is from dbclass
public void ExecuteNonQueryF()
{
try
{
_con.Open();
cmd.ExecuteNonQuery();
}
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
}
you are catching, handling, and suppressing the Exception in ExecuteNonQueryF:
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
}
Though this handles the Exception by showing the message, it causes the code to continue executing; the Exception won't be raised to the caller.
If you add throw after your MessageBox.Show is executed, the Exception will be raised to the caller and execution stops.
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
throw;
}
Another option is to completely remove that try-catch in ExecuteNonQueryF - letting the caller (your button onclick method) handle the Exception.
you need to throw an explicit exception in ExecuteNonQuery's catch block like
throw new Exception(ex)
and then in calle's catch block you need to write "return" to return from function. This will stop furter execution of function.
If you want the Exception will be raised to the caller and execution stops, then you must use throw at the last line of your catch block.
catch (System.Exception ex)
{
/*
write your desire code. then throw
*/
throw;
}

Task.Run on web farm not running correctly

I have a call to write to a log file whenever the API is called. This works flawlessly on single machine but as soon as it is moved to a web farm, then nothing gets written. No errors are raised either.
Here is how things are arranged
Call to API
[HttpGet]
public model.Returns Get([FromUri] model.Requests requests)
With this function, Get, is a call to write to the log file like so
//record request
Task.Run(() => writers.WriteApiLogAsync(requests));
Within the WriteApiLogAsync is this
logs.Add(new model.Log()
{
Type = requests.t,
When = DateTime.Now,
PhoneId = requests.p,
Location = requests.l,
Phone = requests.ph,
PhoneType = requests.pt
});
//file is locked, attempt write on next round but stack log entries
if (logLocker.IsWriterLockHeld) return;
try
{
var result = await writeLogs(logs);
if(result) logLocker.ReleaseWriterLock();
}
catch (OutOfMemoryException ex)
{
WriteErrorAsnc(ex.Message, ex.ToString(), "WriteApiLogAsync_OutOfMemoryException");
logs.Clear();
logLocker.ReleaseWriterLock();
}
catch (IOException ex)
{
WriteErrorAsnc(ex.Message, ex.ToString(), "WriteApiLogAsync_IOException");
logs.Clear();
logLocker.ReleaseWriterLock();
}
catch (Exception ex)
{
WriteErrorAsnc(ex.Message, ex.ToString(), "WriteApiLogAsync_Exception");
logs.Clear();
logLocker.ReleaseWriterLock();
}
finally
{
if (logs.Count > 1000)
{
logs.Clear();
logLocker.ReleaseWriterLock();
}
}
logs is set as
private static List<model.Log> logs = new List<model.Log>();
I didn't specify a machine key as I understand it is primarily for encryption/decryption which there isn't any.
Anyone have an idea of the cause or can point to somewhere with same issue?

Exception being thrown multiple times

Basically I am ting to catch any exception off a block of code, and fire said code one.
try {
CODE
catch (Exception e)
{
DO THIS ONCE
}
finally
{
CODE
}
In Depth
So I have been creating a TCP/SOCKET Server. Which can work with multiple clients. And send/recite (I/O) Data. It works well, and has been for a long time now. But I have found in my console that it says this:
This is bad because if it thinks the user disconnected twice it can create many problems. The way I know if a user has disconnected is by sending data to them every 200ms. And if there is a error then print they disconnected remove them from the client list, and disconnect there stream/tcp.
static bool currentlyUsing;
private static void PingClient(Object o)
{
if (!currentlyUsing)
{
if (clientsConnected.Count != 0)
{
foreach (Client c in clientsConnected)
{
try
{
c.tcp.Client.Blocking = false;
c.tcp.Client.Send(new byte[1], 0, 0);
}
catch (Exception e)
{
currentlyUsing = true;
Console.WriteLine("[INFO] Client Dissconnected: IP:" + c.ip + " PORT:" + c.port.ToString() + " Reason:" + e.Message);
clientsConnected.Remove(c);
c.tcp.Close();
break;
}
finally
{
currentlyUsing = false;
}
GC.Collect();
}
}
}
Is there a way to make it so it catches it only once, or catches it multiple times but only fires the code I want once?
If I understand your question correctly: you want to try to run the code on each iteration of the foreach block, and always run the finally code for each iteration, but only run the catch code once?
If so:
Before the foreach block, define:
bool caught = false;
And then after:
catch (Exception e)
{
if (caught == false)
{
caught = true;
...
}
}
I was making multiple timers. So it overlapped.

Try inside catch to ensure finally executes

I have to process items off a queue.
Deleting items off the queue is a manual call to Queue.DeleteMessage. This needs to occurs regardless of whether or not the processing succeeds.
var queueMessage = Queue.GetMessage();
try
{
pipeline.Process(queueMessage);
}
catch (Exception ex)
{
try
{
Logger.LogException(ex);
}
catch { }
}
finally
{
Queue.DeleteMessage(queueMessage);
}
Problem:
On failure, I log the error to some data store. If this logging fails (perhaps the data store is not available), I still need the message to be deleted from the queue.
I have wrapped the LogException call in another try catch. Is this the correct way or performing thing?
Following code is enough. finally blocks execute even when exception is thrown in catch block.
var queueMessage = Queue.GetMessage();
try
{
pipeline.Process(queueMessage);
}
catch (Exception ex)
{
Logger.LogException(ex);
}
finally
{
Queue.DeleteMessage(queueMessage);//Will be executed for sure*
}
The finally block always executes, even if it throws an unhandled error (unless it end the app). So yes.

Handling Error "WebDev.WebServer.Exe has stopped working"

Is there a way to handle the error "WebDev.WebServer.Exe has stopped working" in ASP.NET and keep the page running or even the just the WebServer running? Or is this an impossible task and is essentially like asking how to save someone's life after they've died?
I have the error-causing code inside a try/catch block, but that doesn't make a difference. I've also tried registering a new UnhandledExceptionEventHandler, but that didn't work either. My code is below in case I'm doing something wrong.
Also to be clear, I'm not asking for help on how to prevent the error; I want to know if and when the error happens if there's anything I can do to handle it.
UPDATE 1: TestOcx is a VB6 OCX that passes a reference of a string to a DLL written in Clarion.
UPDATE 2: As per #JDennis's answer, I should clarify that the catch(Exception ex) block is not being entered either. If I removed the call to the OCX from the try\catch block it still won't reach the UnhandledException method. There are essentially two areas that don't ever get executed.
UPDATE 3: From #AndrewLewis, I tried to also add a regular catch block to catch any non-CLS compliant exceptions, and this did not work either. However, I later found that since .NET 2.0 on, all non-CLS exceptions are wrapped inside RuntimeWrappedException so a catch (Exception) will catch non-CLS compliant exceptions too. Check out this other question here for more info.
public bool TestMethod()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
string input = "test";
string result = "";
try
{
TestOcx myCom = new TestOcx();
result = myCom.PassString(ref input); // <== MAJOR ERROR!
// do stuff with result...
return true;
}
catch (Exception ex)
{
log.Add("Exception: " + ex.Message); // THIS NEVER GETS CALLED
return false;
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// THIS NEVER GETS CALLED
try
{
Exception ex = (Exception)e.ExceptionObject;
log.Add("Exception: " + ex.Message);
}
catch (Exception exc)
{
log.Add("Fatal Non-UI Error: " + exc.Message);
}
}
You should try catching non-CLS compliant exceptions to make sure nothing is being thrown (keep in mind you don't want to do this in production, always be specific!):
try
{
TestOcx myCom = new TestOcx();
result = myCom.PassString(ref input); // <== MAJOR ERROR!
// do stuff with result...
return true;
}
catch (Exception ex)
{
log.Add("Exception: " + ex.Message); // THIS NEVER GETS CALLED
return false;
}
catch
{
//do something here
}
Your code reads //THIS NEVER GETS CALLED.
If you catch the exception it is no longer un-handled. this is why it doesn't fire an unhandledexception event.

Categories