-1

Hi all I just had a quick question for you all. For whatever reason, a piece of code periodically does not return and I am not 100% sure yet. To combat this for now, I want to know, using the Close() method below, is there a way to put a timeout on it? So, if it does not finish within 1 minute or so, it just moves on?

Any advice would be appreciated. Thank you,

If it makes any difference, the original writer who wrote this noted that he believed it hangs on the close() and noted "Maybe Too fast?" (The connection is an oledb connection to Netezza, the whole applications is heavily multi-threaded).

Anyways, for now, I just want to be able to get the application to at least finish instead of hanging on that exception catch.

below is the Close(); which I believe is not returning.

catch(Exception){
    Close(); //-- if we have an error, close everything down and then return the error
    throw;}


public void Close() {
        if (null != Command) {
            Command.Cancel();
            Command.Dispose();
            Command = null;
        }

        if (null != Connection) {
            if (Connection.State != System.Data.ConnectionState.Closed)
                Connection.Close();
            Connection.Dispose();
            Connection = null;
        }

    }
user3494110
  • 417
  • 2
  • 9
  • 25

2 Answers2

0

Rather than timeout on a Method do you really mean timeout on a Command?

Based on that Close() you are sharing Command and Connection.
That is not a good design for a heavily multi-threaded application.
That is not a good design from even a lightly multi-threaded application.

DbCommand has a timeout property

Using statement will perform cleanup (including close)

string connectionString = "";
// Wait for 5 second delay in the command
string queryString = "waitfor delay '00:00:05'";
using (OleDbConnection connection = new OleDbConnection(connectionString )) {
    connection.Open();
    SqlCommand command = new connection.CreateCommand();
    // Setting command timeout to 1 second
    command.CommandText = queryString;
    command.CommandTimeout = 1;
    try {
        command.ExecuteNonQuery();
    }
    catch (DbException e) {
        Console.WriteLine("Got expected DbException due to command timeout ");
        Console.WriteLine(e);
    }
}
paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • Sorry if I am not explaining it well. I don't mean that the query is timing out (I didn't add that above as the rest of the code is several hundred lines long), rather, the command and connection nullification is hanging. – user3494110 Mar 09 '15 at 18:22
0

Assuming you're using .NET 4.0 and above, you can use the TPL to do so using the System.Threading.Tasks.Task object. You create a Task to run a method asynchronously, then Wait on that task for your timeout duration, and if it expires - let the main thread continue.

Task timeoutTask = new Task(Close); // create a Task around the Close method.
timeoutTask.Start(); // run asynchronously.
bool completedSuccessfully = timeoutTask.Wait(TimeSpan.FromMinutes(1));
if (completedSuccessfully)
{
    // Yay!
}
else
{
   logger.Write("Close command did not return in time. Continuing");
}

In this example, the Close method will keep on running in the background, but your main thread can continue.

Avner Shahar-Kashtan
  • 14,492
  • 3
  • 37
  • 63