Member Avatar for squiddog

Hi all -

I need some advice on how to handle multithreading in a GUI. I wrote an application in C# using only the GUI thread (see screenshot) and at times there are "long operations" where the database is being accessed and the right hand pane is being filled with the record data. For example if they click on a tree node, it might take a while for the right hand pane to load, because of database access required and many records. Also they might add many records at once using the Add feature of the right hand pane. I am trying to implement BackgroundWorkers for these operations, but I don't know what to do now, to handle/prevent user clicks during the BW operations. During the long operation the user has the opportunity to click a different node in the tree, or click a menu item, etc. that would cause the long operation to cease midstream.


These are the choices I see right now:
- Make them wait for the operation to complete by setting Form.Enabled to false. But then everything grays out and looks crappy.
- Show a progress dialog modally so they can't click on the form underneath. But that stops execution of the GUI thread so that's no good.
- (Most difficult but probably correct!) Handle the BW cancel feature such that if they click a different tree node or a menu item, the long operation gracefully cancels and they are able to move to the new node/new right hand pane.

I would be interested in "making them wait" (i.e. prevent all clicks until the long operation is complete) but I do not see a way to do this without graying out and looking crappy. Besides I want my app to be professional - i.e. live up to what any user expects to see from a Windows application.

Any help/general tips would be appreciated.

Recommended Answers

All 2 Replies

If you dont thread the app, you will end up with users killing the app out of frustration with the whole "Application not responding" if they toggle away or try and move it etc.

So, arguably, *any* process that could under even some bizarre circumstance take more than a second or so probably should be candidate for threading.

With this in mind, i have some questions:

a) looking at your tree, you could possibly break the query into a number, and run them simultanously
b) is your query efficient

Ok, you can use the asynchrone mode of querying data instead of backgroud worker, I mean the application could request data meanwhile the UI is not going to be freezing I mean the user can interact with the UI at the same time that the data is processed

I give you an example:

namespace CS


{


class Program


{


static void Main(string[] args)


{


string strCnx = "Server=(local);integrated security=SSPI;database=Northwind;async=true";


SqlConnection cnx = new SqlConnection(strCnx);


cnx.Open();


SqlCommand cmd = new SqlCommand("REQUEST", cnx);


cmd.CommandType = CommandType.StoredProcedure;


IAsyncResult ar = cmd.BeginExecuteReader(yourCallBack, cmd);


Console.WriteLine("Le programme continue");


Thread.Sleep(15000);


cnx.Close();


Console.WriteLine("Fin du programme");


}


static void yourCallBack(IAsyncResult ar)


{


SqlCommand cmd = (SqlCommand)ar.AsyncState;


SqlDataReader dr = cmd.EndExecuteReader(ar);


while (dr.Read())


{


Console.Write(dr["CustomerID"]);


}


Console.WriteLine();


dr.Close();


}


}


}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.