So I am using c# windows form with visual studio to query an access database.
When I run with debugger and stop the application from within visual studio there is no problem, however when I run WITHOUT debugger, query the database and then close using X, the process which appears under "Apps" in Task manager becomes a background process. I can have multiple instances of this process if I run the application numerous times.
I would appreciate any information on this, Thanks!
Here is the code I am using.
private void BtnSendQuery_Click(object sender, EventArgs e)
{
ReadDatabase();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
var x = MessageBox.Show("Are you sure you want to exit? ", "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (x == DialogResult.No)
{
e.Cancel = true;
}
else
{
e.Cancel = false;
}
}
private void ReadDatabase()
{
string CONNECTION_STR = #"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source = C:\\Users\\***\\Documents\\db_folder\\access_db.accdb;
Persist Security Info = False";
string query = ""; // query string
OleDbConnection DB_CONNECTION = null;
try
{
DB_CONNECTION = new OleDbConnection(CONNECTION_STR);
DB_CONNECTION.Open();
query = TbInputQuery.Text;
var command = new OleDbCommand(query, DB_CONNECTION);
var str = new StringBuilder();
using (OleDbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
str.AppendLine(reader["ID"].ToString());
}
TbOutputTable.Text = str.ToString();
}
DB_CONNECTION.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (DB_CONNECTION != null)
{
DB_CONNECTION.Close();
}
}
}
}
As general rule, both your connection and cmdSQL or reader should be in a using block.
While your reader is in a using block, the ALL important connection object is not.
In fact, once beyond the using block for connection? You could get away not even having using blocks for the command and reader object.
And even if a trapped error, or UN-trapped error occurs? The using block WILL ALWAYS clean up the connection.
So, for command and reader - not end of world for using block.
But, for connection? yes, always do that.
Project->settings - I would use the connection builder for the connection string - not put in code.
eg this one:
Then use advanced, and make sure you choose ACE (for accdb) or JET (for mdb)
So this:
So, with above setting, then we have ONE spot in the system - never typing connecting string by hand or having to place in the code (makes change of connection very hard).
Also, don't use "any cpu" force the project to x86 for using Access x32
(or if using x64, then force project to that).
So, code say like this:
private void ReadDatabase()
{
string CONNECTION_STR = Properties.Settings.Default.AccessDB;
string query = ""; // query string
try
{
using (OleDbConnection DB_CONNECTION = new OleDbConnection(CONNECTION_STR))
{
using (OleDbCommand command = new OleDbCommand(query, DB_CONNECTION))
{
DB_CONNECTION.Open();
var str = new StringBuilder();
using (OleDbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
str.AppendLine(reader["ID"].ToString());
}
TbOutputTable.Text = str.ToString();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
}
}
Note in above - don't really care about the catch block - as long as the using block for the connection is built - it gets cleaned up no matter what - and even if no try/catch, or if in fact you have one!!
And if a error trigger - still again, note how we do NOT have to clean up, or close the connection.
I'm trying to use SqlBulkCopy to import data into a temp table.
private bool CreateTempTable(IDbConnection conn, byte[] fileByteArray, string tempTableName)
{
try
{
Stream stream = new MemoryStream(fileByteArray);
using (var reader = new CsvReader(stream, false, System.Text.Encoding.UTF8))
{
// Bulk insert the data into a temporary table.
using (SqlBulkCopy bulkCopy = new SqlBulkCopy((SqlConnection)conn))
{
// Import the data into the temp table
bulkCopy.DestinationTableName = tempTableName;
bulkCopy.EnableStreaming = true;
bulkCopy.BatchSize = 20000;
bulkCopy.BulkCopyTimeout = 600;
bulkCopy.WriteToServer(reader);
}
}
}
catch (Exception ex)
{
Logger.Error(ex, $"CreateTempTable(): Exception while creating the TempTable \"{tempTableName}\" - {ex.Message}");
return false;
}
return true;
}
This method is called within another method that runs as async. The connection is passed and maintained by code that looks similar to this:
private async Task<bool> ConsumeAsyn(byte[] fileByteArray, string tempTableName)
{
using (var conn = (SqlConnection)OpenConnection())
{
if (CreateTempTable(conn, fileByteArray, tempTableName))
{
// success
}
else
{
// fail
}
}
}
This is basically how the ConsumeAsync is being called:
public async Task<bool> ProcessNextAsync2()
{
try
{
isIdle = false;
string filePath = ImportFilePickupPath + "\\" + Filename;
byte[] inStream = await LoadImportFileAsync(filePath);
bool consumeSuccess = await Consume(inStream, "##TempTable");
if (consumeSuccess)
{
// Delete the file
DeleteImportFile(filePath);
}
else
{
// Rescedule job
}
isIdle = true;
}
catch (Exception ex)
{
isIdle = true;
}
return isIdle;
}
If I use a small record set, of about a 100 rows in my csv, then everything works. The problem is if I have thousands of records, then the connection gets terminated during the bulk import process.
How can I pass the connection to the method and ensure that it remains open till the bulk import completes?
Maybe an answer, maybe not, but perhaps need to keep your IDisposables (at least/especially the SqlConnection) outside of the async tasks.
This answer over here makes it sound like .NET considers the IDiposables to be out of scope and so disposes them while you're still trying to use them:
SqlBulkCopy.WriteToServer() keep getting "connection is closed"
I were able to fix my problem by dropping support on a third party nuget lib that were dropping my connections. While it's unclear as to why it was happening, getting rid of all async calls and managing the connections myself seemed to have fixed my issue. Bulk imports was working fine however processing the data from the ##Temp table was slow. I decided to keep it all in memory and process it from there.
private bool Consume(byte[] fileByteArray, IDataProcess dataConsumer)
{
try
{
using (var conn = OpenConnection())
{
// Convert byte Array to a stream
Stream stream = new MemoryStream(fileByteArray);
// Create a reader from the stream
using (var reader = new CsvReader(stream, false, System.Text.Encoding.UTF8))
{
RecordEnumerator enumerator = reader.GetEnumerator();
enumerator.MoveNext();
do
{
// Proccess enumerator.Current with dataConsumer
} while (enumerator.MoveNext());
}
}
}
catch (Exception ex)
{
return false;
}
return true;
}
We run the risk of running out of memory but until we get a faster approach, this will have to do.
I am trying to set my ASP row and cell color based off my method in my data class. I have the color set and the method running. The method returns true or false based on the conditions below. How can I prevent the method from running multiple times?
For instance, it runs once and returns correctly then it runs again with "" in the lineNum and brandNum fields with the pack count as the same number as the first run. It processed to run once for every instance of my method call. Then when I actually call the method again it runs everything again. Why is it running more than once and how can I fix this?
output:
lineNum:123 brandNum:456 packCount:15
second run (not asked for)
lineNum:"" brandNum:"" packCount:15
Method to determine if true:
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("#GenNum6", itemNum),
new SqlParameter("#GenTxt9", brandNum)
};
try
{
reader = App_Code.DBHelper.executeQuery(dbConn,
sqlString.ToString(), parameters);
if (reader.HasRows)
{
while (reader.Read())
{
PackCount = reader["PackCount"].ToString();
}
}
reader.Close();
reader.Dispose();
dbConn.Close();
dbConn.Dispose();
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (dbConn != null)
{
try { dbConn.Close(); dbConn.Dispose(); }
catch { }
}
if (reader != null)
{
try { reader.Close(); reader.Dispose(); }
catch { }
}
}
if (Convert.ToInt32(PackCount) <= 12)
{
return true;
}
else
{
return false;
}
Call:
if (lineData.PacksLeft1(L1.Text,L2.Text))
{
myTable.Rows[1].Cells[0].BgColor = "#FE2E2E";
myTable.Rows[1].Cells[1].BgColor = "#FE2E2E";
myTable.Rows[1].Cells[2].BgColor = "#FE2E2E";
myTable.Rows[1].Cells[3].BgColor = "#FE2E2E";
}
There is no need for the finally statement as it performs the same action that is performed in the try statement. I believe that after seeing this piece, if you go back through where it is being called from, you may have it running in a try catch, doing the exact same thing. I would suggest taking the
reader.Close();
reader.Dispose();
dbConn.Close();
dbConn.Dispose();
out of the try block and leaving the finally statement. This way, no matter the outcome, these items are performed.
Finally is only used when you want the code to run something after it has preformed the try statement. Such as:
Try{
//Try this statement, if it works, run it.
}
catch{
//error occurred
}
finally{
//run this code whether the try failed or not.
}
what would happen while searching the file through a string and could i try to continue the loop within the catch block against locked windows file in order to read next file.
TextReader rff = null;
try
{
rff = new StreamReader(fi.FullName);
String lne1 = rff.ReadToEnd();
if (lne1.IndexOf(txt) >= 0)
{
z = fi.FullName;
list22.Add(fi.FullName);
As long as the exception is caught by a try-catch nested inside the loop, you should be able to continue the loop no problem.
I'd say you'll have a try-catch around the statement where you are accessing the file within the loop. Then you can continue the loop after catching any exception.
While catching the exception try to catch only the most specific exception that may be thrown, so if you are looking to handle a locking situation you would look to catch the System.IO.IOException which is raised when files are used by other proccesses.
If you have to do some cleanup to do you should add a finally:
foreach (var fileName in fileNames)
{
var fi = new FileInfo(fileName);
StreamReader reader;
try
{
reader = new StreamReader(fi.FullName);
SomeMethodThatThrowsIOException();
}
catch (IOException ex)
{
continue;
}
finally
{
if (reader != null)
reader.Close();
}
}
or even better (since StreamReader implements IDisposable)
foreach (var fileName in fileNames)
{
try
{
var fi = new FileInfo(fileName);
using (var reader = new StreamReader(fi.FullName))
{
SomeMethodThatThrowsIOException();
}
}
catch (IOException ex) { }
}
One thing that has bugged me with exception handling coming from Python to C# is that in C# there doesn't appear to be any way of specifying an else clause. For example, in Python I could write something like this (Note, this is just an example. I'm not asking what is the best way to read a file):
try
{
reader = new StreamReader(path);
}
catch (Exception)
{
// Uh oh something went wrong with opening the file for reading
}
else
{
string line = reader.ReadLine();
char character = line[30];
}
From what I have seen in most C# code people would just write the following:
try
{
reader = new StreamReader(path);
string line = reader.ReadLine();
char character = line[30];
}
catch (Exception)
{
// Uh oh something went wrong, but where?
}
The trouble with this is that I don't want to catch out of range exception coming from the fact that the first line in the file may not contain more than 30 characters. I only want to catch exceptions relating to the reading of the file stream. Is there any similar construct I can use in C# to achieve the same thing?
Catch a specific class of exceptions
try
{
reader = new StreamReader(path);
string line = reader.ReadLine();
char character = line[30];
}
catch (IOException ex)
{
// Uh oh something went wrong with I/O
}
catch (Exception ex)
{
// Uh oh something else went wrong
throw; // unless you're very sure what you're doing here.
}
The second catch is optional, of course. And since you don't know what happened, swallowing this most general exception is very dangerous.
You could write it like:
bool success = false;
try {
reader = new StreamReader(path);
success = true;
}
catch(Exception) {
// Uh oh something went wrong with opening the file for reading
}
finally {
if(success) {
string line = reader.ReadLine();
char character = line[30];
}
}
You can do this:
try
{
reader = new StreamReader(path);
}
catch (Exception)
{
// Uh oh something went wrong with opening the file for reading
}
string line = reader.ReadLine();
char character = line[30];
But of course, you will have to set reader into a correct state or return out of the method.
Catch more specific exceptions.
try {
reader = new StreamReader(path);
string line = reader.ReadLine();
char character = line[30];
}
catch(FileNotFoundException e) {
// thrown by StreamReader constructor
}
catch(DirectoryNotFoundException e) {
// thrown by StreamReader constructor
}
catch(IOException e) {
// some other fatal IO error occured
}
Further, in general, handle the most specific exception possible and avoid handling the base System.Exception.
You can nest your try statements, too
Exceptions are used differently in .NET; they are for exceptional conditions only.
In fact, you should not catch an exception unless you know what it means, and can actually do something about it.
You can have multiple catch clauses, each specific to the type of exception you wish to catch. So, if you only want to catch IOExceptions, then you could change your catch clause to this:
try
{
reader = new StreamReader(path);
string line = reader.ReadLine();
char character = line[30];
}
catch (IOException)
{
}
Anything other than an IOException would then propagate up the call stack. If you want to also handle other exceptions, then you can add multiple exception clauses, but you must ensure they are added in most specific to most generic order. For example:
try
{
reader = new StreamReader(path);
string line = reader.ReadLine();
char character = line[30];
}
catch (IOException)
{
}
catch (Exception)
{
}
More idiomatically, you would employ the using statement to separate the file-open operation from the work done on the data it contains (and include automatic clean-up on exit)
try {
using (reader = new StreamReader(path))
{
DoSomethingWith(reader);
}
}
catch(IOException ex)
{
// Log ex here
}
It is also best to avoid catching every possible exception -- like the ones telling you that the runtime is about to expire.
Is there any similar construct I can use in C#
to acheive the same thing?
No.
Wrap your index accessor with an "if" statement which is the best solution in your case in case of performance and readability.
if (line.length > 30) {
char character = line [30];
}
After seeing the other suggested solutions, here is my approach:
try {
reader = new StreamReader(path);
}
catch(Exception ex) {
// Uh oh something went wrong with opening the file stream
MyOpeningFileStreamException newEx = new MyOpeningFileStreamException();
newEx.InnerException = ex;
throw(newEx);
}
string line = reader.ReadLine();
char character = line[30];
Of course, doing this makes sense only if you are interested in any exceptions thrown by opening the file stream (as an example here) apart from all other exceptions in the application. At some higher level of the application, you then get to handle your MyOpeningFileStreamException as you see fit.
Because of unchecked exceptions, you can never be 100% certain that catching only IOException out of the entire code block will be enough -- the StreamReader can decide to throw some other type of exception too, now or in the future.
You can do something similar like this:
bool passed = true;
try
{
reader = new StreamReader(path);
}
catch (Exception)
{
passed = false;
}
if (passed)
{
// code that executes if the try catch block didnt catch any exception
}
I have taken the liberty to transform your code a bit to demonstrate a few important points.
The using construct is used to open the file. If an exception is thrown you will have to remember to close the file even if you don't catch the exception. This can be done using a try { } catch () { } finally { } construct, but the using directive is much better for this. It guarantees that when the scope of the using block ends the variable created inside will be disposed. For a file it means it will be closed.
By studying the documentation for the StreamReader constructor and ReadLine method you can see which exceptions you may expect to be thrown. You can then catch those you finde appropriate. Note that the documented list of exceptions not always is complete.
// May throw FileNotFoundException, DirectoryNotFoundException,
// IOException and more.
try {
using (StreamReader streamReader = new StreamReader(path)) {
try {
String line;
// May throw IOException.
while ((line = streamReader.ReadLine()) != null) {
// May throw IndexOutOfRangeException.
Char c = line[30];
Console.WriteLine(c);
}
}
catch (IOException ex) {
Console.WriteLine("Error reading file: " + ex.Message);
}
}
}
catch (FileNotFoundException ex) {
Console.WriteLine("File does not exists: " + ex.Message);
}
catch (DirectoryNotFoundException ex) {
Console.WriteLine("Invalid path: " + ex.Message);
}
catch (IOException ex) {
Console.WriteLine("Error reading file: " + ex.Message);
}
Sounds like you want to do the second thing only if the first thing succeeded. And maybe catching different classes of exception is not appropriate, for example if both statements could throw the same class of exception.
try
{
reader1 = new StreamReader(path1);
// if we got this far, path 1 succeded, so try path2
try
{
reader2 = new StreamReader(path2);
}
catch (OIException ex)
{
// Uh oh something went wrong with opening the file2 for reading
// Nevertheless, have a look at file1. Its fine!
}
}
catch (OIException ex)
{
// Uh oh something went wrong with opening the file1 for reading.
// So I didn't even try to open file2
}
There might not be any native support for try { ... } catch { ... } else { ... } in C#, but if you are willing to shoulder the overhead of using a workaround, then the example shown below might be appealing:
using System;
public class Test
{
public static void Main()
{
Example("ksEE5A.exe");
}
public static char Example(string path) {
var reader = default(System.IO.StreamReader);
var line = default(string);
var character = default(char);
TryElse(
delegate {
Console.WriteLine("Trying to open StreamReader ...");
reader = new System.IO.StreamReader(path);
},
delegate {
Console.WriteLine("Success!");
line = reader.ReadLine();
character = line[30];
},
null,
new Case(typeof(NullReferenceException), error => {
Console.WriteLine("Something was null and should not have been.");
Console.WriteLine("The line variable could not cause this error.");
}),
new Case(typeof(System.IO.FileNotFoundException), error => {
Console.WriteLine("File could not be found:");
Console.WriteLine(path);
}),
new Case(typeof(Exception), error => {
Console.WriteLine("There was an error:");
Console.WriteLine(error);
}));
return character;
}
public static void TryElse(Action pyTry, Action pyElse, Action pyFinally, params Case[] pyExcept) {
if (pyElse != null && pyExcept.Length < 1) {
throw new ArgumentException(#"there must be exception handlers if else is specified", nameof(pyExcept));
}
var doElse = false;
var savedError = default(Exception);
try {
try {
pyTry();
doElse = true;
} catch (Exception error) {
savedError = error;
foreach (var handler in pyExcept) {
if (handler.IsMatch(error)) {
handler.Process(error);
savedError = null;
break;
}
}
}
if (doElse) {
pyElse();
}
} catch (Exception error) {
savedError = error;
}
pyFinally?.Invoke();
if (savedError != null) {
throw savedError;
}
}
}
public class Case {
private Type ExceptionType { get; }
public Action<Exception> Process { get; }
private Func<Exception, bool> When { get; }
public Case(Type exceptionType, Action<Exception> handler, Func<Exception, bool> when = null) {
if (!typeof(Exception).IsAssignableFrom(exceptionType)) {
throw new ArgumentException(#"exceptionType must be a type of exception", nameof(exceptionType));
}
this.ExceptionType = exceptionType;
this.Process = handler;
this.When = when;
}
public bool IsMatch(Exception error) {
return this.ExceptionType.IsInstanceOfType(error) && (this.When?.Invoke(error) ?? true);
}
}
If you happen to be in a loop, then you can put a continue statement in the catch blocks. This will cause the remaining code of that block to be skipped.
If you are not in a loop, then there is no need to catch the exception at this level. Let it propagate up the call stack to a catch block that knows what to do with it. You do this by eliminating the entire try/catch framework at the current level.
I like try/except/else in Python too, and maybe they will get added to C# some day (just like multiple return values were). But if you think about exceptions a little differently, else blocks are not strictly necessary.