Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Connect to database in separate thread

I have an application that sits in the taskbar and periodically checks a database (via SQLConnection). If the database is unreachable, it just shows a red status on the notify icon, and nothing else. This is intended since the users will be on laptops traveling between facilities, and the database is only reachable on an internal network or when connected via VPN.

The issue I'm having is that when the database is unreachable, I'd still like the notify icon context menu to be responsive. Currently if the user tries to interact with the menu while the database is attempting to connect, the thread is locked up with the connection attempt.

What I'd like is for the database connection to happen in a separate thread, but I know that sharing the connection object between threads is a bad thing to try to do. Once the database has connected, I need to query it from the original thread. Is there any good way to do this?

I know that I could have a function that rus in a new thread and simply checks if the connection fails or not, then if that returns success the original thread could move on and connect it's own database object. But that method seems like a bad workaround. Ideas?

Thanks!


Thanks for the suggestions - I have learned quite a bit from them. In the end, I did what I should have done from the start. The main (UI) thread just kicks off a new thread (which includes database object creation and connection) whenever a periodic database update is needed.

So, like HenkHolterman suggested in a comment to my original message, I really did not need to create the database and run operations with it in separate threads.

I will definitely be interested in using SqlConnection.OpenAsync once I've made the upgrade to VS2010.

Thanks again.

like image 898
user1259576 Avatar asked Apr 18 '12 16:04

user1259576


People also ask

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

A SqlConnection does not have thread affinity requirements so you can create and open it on a separate thread and pass the reference back to the UI thread. So long as you do not call any properties or methods on the same instance simultaneously from multiple threads you should not have any problems.

Use the Task class (System.Threading.Task) to start this operation in the background and then call ContinueWith to transfer ownership of the instance back to the UI thread.

public class TrayIconForm : Form
{
  private SqlConnection connection = null;

  private void Form_Load(object sender, EventArgs args)
  {
    TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();

    Task.Factory.StartNew(() =>
      {
        var sql = new SqlConnection();
        sql.ConnectionString = "your connection string";
        sql.Open();
        return sql;
      }).ContinueWith((task =>
      {
        connection = task.Result;
        // You can access other UI elements here as needed.
      }), ui);
  }
}

With the new async and await keywords to be introduced in C# 5.0 and available now via the Async CTP you can do this.

private async void Form_Load(object sender, EventArgs args)
{
  connection = await Task.Run(() =>   // TaskEx.Run in the CTP
    {
      var sql = new SqlConnection();
      sql.ConnectionString = "your connection string";
      sql.Open();
      return sql;
    });
}
like image 57
Brian Gideon Avatar answered Sep 28 '22 05:09

Brian Gideon


I would recommend using the new C# Async CTP. This will allow you to stay on the UI thread, therefore reducing complexity.

SqlConnection.OpenAsync

like image 20
GregC Avatar answered Sep 28 '22 06:09

GregC