When using the back ground worker class to call a method within a try catch statement, and a try catch statement is in the method, which one catches the exception?
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
Do();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show("Error:" + e.Result + ex.Message);
}
}
And:
private void Do ()
{
try
{
//Do something, open a file etc.
FileStream fs = new FileStream("file.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch (Exception e)
{
System.Windows.MessageBox.Show("Error:" + e.Result + ex.Message);
}
}
Called with: backgroundWorker1.RunWorkerAsync();
Is there a way to make sure the exception is handled within the method? so the backgroundworker doesn't break?
The inner one since this catch is "closer" to the "error"
this one :
private void Do ()
{
try
{
//Do something, open a file etc.
FileStream fs = new FileStream("file.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch (Exception e)
{
System.Windows.MessageBox.Show("Error:" + e.Result + ex.Message);
}
}
Related
I have this code and I don't know why it pops up this error message :
"Invalid Operation Exception was unhandled by user code".
This error comes out when I press the save button.
The purpose of this program is to save the text from one textbox in the Mytest.txt file and then from the file to the textbox1. I would really appreciate some help here.
Thank you in advance.
public MainPage()
{
this.InitializeComponent();
}
private void buttonsave_Click(object sender, RoutedEventArgs e)
{
string path = #"C:\Users\geora\Mytest.txt";
if(!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine(textBox.Text);
}
}
}
private void buttonshow_Click(object sender, RoutedEventArgs e)
{
string path = #"C:\Users\geora\Mytest.txt";
using (StreamReader sr = File.OpenText(path))
{
string s = "";
s = sr.ReadLine();
textBox1.Text = s;
}
}
You have opened files but not closed the file.This Might be the issue
StreamReader sr = File.OpenText(path)
You need to close it. Using does this for you (and disposes it so it's GC'd sooner):
Or alternatively in .Net 2 you can use the new File. static members, then you don't need to close anything:
variable = File.ReadAllText(path);
Additional to your exception
WPF Version:
private void loadButton_Click(object sender, RoutedEventArgs e)
{
try
{
textBox.Text = File.ReadAllText(#"d:\test.txt");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void saveButton_Click(object sender, RoutedEventArgs e)
{
try
{
File.WriteAllText(#"d:\test.txt", textBox.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
UWP Version:
using System;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
...
private async void buttonSave_Click(object sender, RoutedEventArgs e)
{
try
{
var storageFolder = ApplicationData.Current.LocalFolder;
var sampleFile = await storageFolder.CreateFileAsync("sample.txt",
CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(sampleFile, textBox.Text);
var msgbox = new MessageDialog(sampleFile.Path, "Your file is in");
await msgbox.ShowAsync();
}
catch (Exception ex)
{
var msgbox = new MessageDialog(ex.ToString(), "Error");
await msgbox.ShowAsync();
}
}
private async void buttonLoad_Click(object sender, RoutedEventArgs e)
{
try
{
var storageFolder = ApplicationData.Current.LocalFolder;
var sampleFile = await storageFolder.GetFileAsync("sample.txt");
textBox.Text = await FileIO.ReadTextAsync(sampleFile);
}
catch (Exception ex)
{
var msgbox = new MessageDialog(ex.ToString(), "Error");
await msgbox.ShowAsync();
}
}
I have been trying to log exceptions to a file. I can get the exception with all its details and when I step through the class the StreamWriter logWriter doesn't seem to do what I thought it would do.
public static void Write(Exception exception)
{
string logfile = String.Empty;
try
{
logfile = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["ErrorLog"]).ToString();
StreamWriter logWriter;
if (File.Exists(logfile))
{
logWriter = File.AppendText(logfile);
}
else
{
logWriter = File.CreateText(logfile);
logWriter.WriteLine("=>" + DateTime.Now + " " + " An Error occurred: " + exception.StackTrace +
" Message: " + exception.Message + "\n\n");
logWriter.Close();
throw exception;
}
}
catch (Exception e)
{
throw;
}
}
I would of thought the logWriter would of written the exception details to the File.AppendText(logfile)but it doesn't and just jumps straight out the if statement. All the details of the exception are in the else statement, I have tried to put this in theif` condition but throws an exception!
How can I write the exception to the file. I got the code from CodeProject. Everything thing works fine except writing the exception to the file.
Try it correctly and throw the exception outside of the method:
public static void Write(Exception exception)
{
string logfile = String.Empty;
try
{
logfile = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["ErrorLog"]).ToString();
if(File.Exists(logfile))
{
using(var writer = new StreamWriter(logfile, true))
{
writer.WriteLine(
"=>{0} An Error occurred: {1} Message: {2}{3}",
DateTime.Now,
exception.StackTrace,
exception.Message,
Environment.NewLine
);
}
}
}
catch(Exception e)
{
throw;
}
}
Throw it outside:
catch(Exception e)
{
Write(e);
throw;
}
This snippet works to write into a file
public static bool WriteResult(string result)
{
using (StreamWriter sr = File.AppendText("result.txt"))
{
sr.WriteLine(result);
sr.Flush();
return true;
}
return false;
}
For you, you have to adapt it a bit to meet your requirments :
public static void Write(Exception exception) {
try {
using(StreamWriter sr = File.AppendText("result.txt")) //new StreamWriter("result.txt", Encoding. ))
{
sr.WriteLine("=>" + DateTime.Now + " " + " An Error occurred: " + exception.StackTrace +
" Message: " + exception.Message + "\n\n");
sr.Flush();
}
catch (Exception e) {
throw;
}
}
A nice template method i wrote goes with every project.
private static void AddLog(string strMsg)
{
#region logfolder creation
if (!System.IO.Directory.Exists("C:\\appname"))
{
System.IO.Directory.CreateDirectory("C:\\appname");
if (!System.IO.Directory.Exists("C:\\appname\\Logs"))
{
System.IO.Directory.CreateDirectory("C:\\appname\\Logs");
}
}
#endregion
#region logfile creation
FileStream fsc;
logFileName = "C:\\appname\\Logs\\appnameLog_" + DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + ".txt";
if (!System.IO.File.Exists(logFileName))
{
fsc = new FileStream(logFileName, FileMode.Create, FileAccess.Write);
fsc.Close();
}
#endregion
#region logging
using (FileStream fs = new FileStream(logFileName, FileMode.Append, FileAccess.Write))
{
using (StreamWriter sr = new StreamWriter(fs))
{
try
{
sr.WriteLine(strMsg);
}
catch (Exception exc)
{
EventLogEntry(exc.ToString().Trim(), EventLogEntryType.Error, 7700);
}
}
}
#endregion
}
This is really short question. I don't understand try-catch mechanism completely.
This is my current code:
public static void WriteText(string filename, string text)
{
try
{
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
file.Write(text);
file.Close();
}
catch(Exception exc)
{
MessageBox.Show("File is probably locked by another process.");
}
}
Background:
Im writing application that shares configuration files with another application.
I need some dialog messagebox with "retry" and "abort" buttons, when that file is used by other application. When that message will appear - I will close that other application and I will try to rewrite that file again by pressing "Retry" button.
Whatr we have is using a counter for re-tries and possibly a thread sleep.
So something like
int tries = 0;
bool completed = false;
while (!completed)
{
try
{
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
file.Write(text);
file.Close();
completed = true;
}
catch(Exception exc)
{
tries++;
//You could possibly put a thread sleep here
if (tries == 5)
throw;
}
}
Even though there's a good answer already I'll submit one that's more tuned towards the OP's question (let the user decide instead of using a counter).
public static void WriteText(string filename, string text)
{
bool retry = true;
while (retry)
{
try
{
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
file.Write(text);
file.Close();
retry=false;
}
catch(Exception exc)
{
MessageBox.Show("File is probably locked by another process.");
// change your message box to have a yes or no choice
// yes doesn't nothing, no sets retry to false
}
}
}
If you need more info on how to implement the messagebox check out the following links;
http://msdn.microsoft.com/en-us/library/0x49kd7z.aspx
MessageBox Buttons?
I would do it like that:
public static void WriteText(string filename, string text, int numberOfTry = 3, Exception ex = null)
{
if (numberOfTry <= 0)
throw new Exception("File Canot be copied", ex);
try
{
var file = new System.IO.StreamWriter(filename);
file.Write(text);
file.Close();
}
catch (Exception exc)
{
WriteText(filename,text,--numberOfTry,ex);
}
}
I like it more like this (example tries to save a RichTextBox on close and allows retrying save or aborting close):
protected override void OnClosing(CancelEventArgs e)
{
if (richTextBox_Query.Modified)
{
DialogResult result;
do
try
{
richTextBox_Query.SaveFile(
Path.ChangeExtension(Application.ExecutablePath, "sql"),
RichTextBoxStreamType.UnicodePlainText);
result = DialogResult.OK;
richTextBox_Query.Modified = false;
}
catch (Exception ex)
{
result = MessageBox.Show(ex.ToString(), "Exception while saving sql query",
MessageBoxButtons.AbortRetryIgnore);
e.Cancel = result == DialogResult.Abort;
}
while (result == DialogResult.Retry);
}
base.OnClosing(e);
}
I'm trying to understand how I'm going to use Throw in my code. I have a MainForm class to handle the Windows Form GUI and then I have the Manager class to read and save data from/to files.
I use Try/Catch in both classes, but my instructor want me to use Throw in the Manager class and despite that I'm reading about it, I don't get the point what it will do? Will Throw affect the Try/Catch in the MainForm class?
I also use a message box in the manager class if an exception is catched, but no message box are allow to be in the manager according to the instructor, so how would I do then? Can I use the message box in MainForm class only? Preciate some help to understand and expand my knowledge! Thanks!
MainForm class:
try
{
motelManager.SaveToFile(file);
}
catch
{
MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
Manager class:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
if (filestream != null) filestream.Close();
}
your manager class should look like this:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
if (filestream != null) filestream.Close();
throw;
// but don't use
// throw ex;
// it throws everything same
// except for the stacktrace
}
// or do it like this
//catch(Exception ex)
//{
// throw;
// but don't use
// throw ex;
// it throws everything same
// except for the stacktrace
//}
//finally
//{
// if (filestream != null) filestream.Close();
//}
}
and in your main class:
try
{
motelManager.SaveToFile(file);
}
catch (Exception e)
{
MessageBox.Show("Ett fel uppstod!", "Varning!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
Throw simply raises the exception to the calling function. (in this case, whoever calls SaveToFile). If there is an error handler there, it will be caught, otherwise it will continue up the call stack until it is caught or at the top level.
It is better to handle the Exception in terms of presentation to the user in the Form - simply because in a larger well structured system the Manager object may well not have any connection to the GUI.
General rule is to catch the exception in the backend [Manager] class to cleanup any resources (i.e. close the file) and then re-throw the exception from the exception handler as follows:
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch(Exception ex)
{
/*
* cleanup resources and rethrow the exception for catching and handling elsewhere
*/
if (filestream != null)
filestream.Close();
throw;
}
}
public void SaveToFile(string filePath)
{
try
{
string newFilePath = filePath.Replace(".bin", "");
filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch (Exception ex)
{
if (filestream != null) filestream.Close();
//what you want
//MessageBox.Show(ex.Message, "Warning!");
throw (new Exception("Your custom message"));
}
}
And in your manager:
try
{
manager.SaveToFile(filePath);
}
catch (Exception ex)
{
// here shows your 'Your custom message'
MessageBox.Show(ex.Message);
}
In an application with multiple tiers, exceptions that occur in underlying layers are not sent as is to higher layer or to the calling application.
For instance, if something goes wrong in the database related code, you do not send it to client application or to higher layer. Reason for doing so is to provide users with friendly error messages. Say, you had foreign key reference errors during delete operation, you can:
Log the exception information.
Replace with with a user friendly exception message and throw it to layer above.
Layer above may wrap this exception to another higher level message and then throw it ahead. This is similar to what you have been asked to do.
In your code in Manager class, check how many exceptions can possibly occur. If you are using VS, tooltip/help text provides that information. If you are not using VS, check out MSDN for this information.
In the form, handle all the exceptions that can be thrown by manager layer and also a generic exception if something terribly wrong happens. IMHO, this is how your code in manager layer should like
try
{
string newFilePath = filePath.Replace(".bin", "");
FileStream filestream = new FileStream(newFilePath + ".bin", FileMode.Create);
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
catch (ArgumentNullException argNullException)
{
// Log current exception
// Wrap it under your exception type
CustomWrapException customWrap = new CustomWrapException();
customWrap.Message = "Your custom message here.";
customWrap.InnerException = argNullException;
throw customWrap;
}
catch (SecurityException securityException)
{
// Log current exception
// Replace current exception with you custom exception
CustomReplaceException replaceException = new CustomReplaceException();
replaceException.Message = "Your custom message here.";
throw replaceException;
}
finally
{
// Close stream and dispose objects here
}
Your form should be having exception handling like this:
try
{
// Call mananger code from here
}
catch (CustomWrapException wrapException)
{
// replace/wrap if desired
// Display message to user
}
catch (CustomReplaceException replaceException)
{
// replace/wrap if desired
// Display message to user
}
catch (Exception exception)
{
// This is for everything else that may go wrong apart from known possible exceptions
// Display message to user
}
finally
{
}
HTH.
you can use Application ThreadException to catch any exception. And your save logic to wrap with using instead of try catch, in this case it will close your stream.
public void SaveToFile(string filePath)
{
string newFilePath = filePath.Replace(".bin", "");
using(var filestream = new FileStream(newFilePath + ".bin", FileMode.Create))
{
BinaryFormatter b = new BinaryFormatter();
b.Serialize(filestream, animals);
}
}
in the entry point (static void main()) subscribe to this event.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Application.ThreadException += Application_ThreadException;
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show(".......");
}
it is like this...
try { }
catch(Exception e)
{ throw }
When it throws the exception, it will change the source and the stack trace, so that it will appear that the exception has been thrown from this method, from that very line throw e on the method containing that try-catch block.
Im trying to capture connection problem when using WebClient. Example, unreachable, timeout etc. Code belows doesnt work, as if there is nothing wrong.
WebClient wc = new WebClient();
try
{
wc.UploadFileAsync(new Uri(#"ftp://tabletijam/FileServer/upload.bin"), Directory.GetCurrentDirectory() + #"\crypto.bin");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
The code you are using, just sends the file ... you need to implement the Async part.
WebClient webClient = new WebClient();
webClient.UploadFileAsync(address, fileName);
webClient.UploadProgressChanged += WebClientUploadProgressChanged;
webClient.UploadFileCompleted += WebClientUploadCompleted;
...
void WebClientUploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
{
Console.WriteLine("Download {0}% complete. ", e.ProgressPercentage);
}
void WebClientUploadCompleted(object sender, UploadFileCompletedEventArgs e)
{
// The upload is finished, clean up
}
try
{
// trying to make any operation on a file
}
catch (IOException error)
{
if(error is FileNotFoundException)
{
// Handle this error
}
}
use this code but with your scenario