Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Dear All,

I have designed a class which implements AsyncCallBack to retrieve long process Data:
Here is my code:

C#
class GetAllData
    {
        SqlConnection cnn = new SqlConnection("Data Source=DEVELOPER;Initial Catalog=ERPLiveDB;Integrated Security=True;Asynchronous Processing=True");
        SqlCommand cmd = new SqlCommand();
        DataTable tblResult = new DataTable();
        private static int counter = 0;
        protected ToolStripStatusLabel lblval;

        public DataTable GetByQuery(string Query, ref ToolStripProgressBar pb,ref ToolStripStatusLabel lbl)
        {
            cmd = cnn.CreateCommand();
            cmd.CommandText = Query;
            lblval = lbl;
            try
            {
                cnn.Open();
                AsyncCallback callback = new AsyncCallback(RetrieveDataCallback);
                           
                
                cmd.BeginExecuteReader(callback, cmd,CommandBehavior.CloseConnection);
                //show status of processing in progress bar. 
                while (counter < 1)
                {
                    lbl.Text = pb.Value.ToString() + " %" + "Retrieved.";
                    if (pb.Value != 100)
                    {
                        pb.Value += 2;
                    }
                    else
                    {
                        pb.Value = 0;
                        //lbl.Text = "";
                    }
                    Thread.Sleep(50);
                    lbl.Text = pb.Value.ToString() + " %" + "Retrieved.";
                }
                pb.Value = 100;
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                cnn.Close();
            }
            return (tblResult);
        }
        private void RetrieveDataCallback(IAsyncResult result)
        {
            SqlDataReader dr = null;
            try
            {
                SqlCommand comm = (SqlCommand)result.AsyncState;
               
                dr = comm.EndExecuteReader(result);
                //while (dr.Read())
                //{
                //    lblval.Text = lblval.Text + ".";
                //}
                //tblResult.Load(dr, LoadOption.OverwriteChanges);
                tblResult.Load(dr);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                try
                {
                    if (!dr.IsClosed)
                    {
                        dr.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString());
                }
                Interlocked.Increment(ref counter);
            }
        }
    }


I have designed this class from an example.

Is there any way to implement AsyncCallBack method with parameters...?
AsyncCallback callback = new AsyncCallback(RetrieveDataCallback);
RetrieveDataCallBack with IAsyncResult and other parameters...

Please help.
Posted

1 solution

Are you ready to consider a reasonable alternative? I think that asynchronous APIs are just the leftovers of the days when threading was not a commonplace. Threading implementation is more straightforward, easier to design and debug and more universal. It has sequential logic; you have more control. In return, you have to focus on thread synchronization, but synchronization are universal, not specific to application, so you can use the same techniques over and over.

I described my schema of database polling here: Polling Database with Timer[^].

It can be applied to your problem as well.

[EDIT: answering a follow-up question on samples; please see commends below]

Unfortunately, the shortest comprehensive code sample would require too much of code, more then even I usually write in this forum (I tend to write much longer answers compared to an average one).

Please see my other referenced above. First, it references some code showing a pretty good ways working with the thread using a thread wrapper. The following answers contain detailed code samples and explain why this is a good way:
How to pass ref parameter to the thread[^],
change paramters of thread (producer) after it started[^].

You can work with ADO.NET in such separate thread, but not with to UI. Also, the thread polling the database should be is a such separate thread, which can get to a wait state waiting for the event wait handle set in the timer. When the data is retrieved from the database, you should notify the UI thread with new data, for example, through binding.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

Assuming you know how to work with ADO.NET, you now have all the missing pieces. Any further questions? You are welcome to ask them, but I would be able to effectively answer if they are related to the design elements I have just depicted.

—SA
 
Share this answer
 
v3
Comments
BhavinBhatt 19-Apr-12 1:06am    
Not getting exactly..
ACtually I am designing an ERP for my company in SQL SErver /C#.net winforms.
I want to make an application with real asynchronous data access in all my data transaction forms. I have find a solution from Net and implemented it.

Suggest me any possible ways with example please.

Thanks.
Sergey Alexandrovich Kryukov 19-Apr-12 12:26pm    
The good way is to do the data access in a separate thread, and never in UI thread.
--SA
BhavinBhatt 20-Apr-12 5:14am    
any example? please...? or steps to implement this.

I have a base form which contains BindingNavigator and BindingSource as well as toolstripbar with Progressbar and label.

All these controls are derived in each transaction form and methods on the base form are virtual void..

please help.
Sergey Alexandrovich Kryukov 20-Apr-12 15:33pm    
It would need too much time. Please see at my updated answer, after [EDIT], ask further questions...
--SA
Nelek 20-Apr-12 15:59pm    
+5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900