-2

My problem is simply that my SQL query takes over 2 minutes to complete and I can't have my application freezing up while it tries to get all that data. I've tried multi-threading but I keep running into an error that I am pretty sure you'll recognize. My code is under that.

Cross-thread operation not valid: Control 'labelEdit1' accessed from a thread other than the thread it was created on.

private void Form_Load(object sender, EventArgs e)
    {
        startup = new Thread(loadInThread);
        startup.Start();            
    }

private void loadInThread()
{
    //getsDataFromSQL() is the method that takes over 2 minutes to do
    //it returns a String Array if that is helpful
    comboEdit1.Properties.Items.AddRange(getsDataFromSQL());   
    startup.Abort();
}

If there are better ways to do this then please let me know, all I need is for the application to not freeze up and the data to get loaded into the comboEdit. Also I know the SQL statements could be optimized but that's not what this question is about, so please don't suggest it,.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
5tar-Kaster
  • 910
  • 2
  • 12
  • 30
  • Have you done any research for cross thread exceptions? The very first related question to this question has the title "Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on"... – Daniel Kelley Aug 22 '13 at 09:29
  • http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the?rq=1 – Sriram Sakthivel Aug 22 '13 at 09:30
  • I have done research, I know that there is a backgroundworker and whatnot however I read that the backgorund worker shifts the process to the main thread anyways, so that is sort of not a solution... hence I asked for advice on a possible different way to do it – 5tar-Kaster Aug 22 '13 at 09:36
  • You should read the links posted as they show you how to avoid this problem when your processing has completed (by marshalling the UI update to the UI thread instead of trying to do it on the worker thread) – Charleh Aug 22 '13 at 09:46

2 Answers2

1

You need to use dispatcher here. This is because you cannot access controls owned by UI thread from another thread. Check this link here. I have not checked this for compilation errors but this should do the trick for you with a little modification of course.

private void loadInThread()
{
    //getsDataFromSQL() is the method that takes over 2 minutes to do
    //it returns a String Array if that is helpful
    comboEdit1.Dispatcher.BeginInvoke((Action)(() =>
    {
        comboEdit1.Properties.Items.AddRange(getsDataFromSQL());   
    }));
    startup.Abort();
}
samar
  • 5,021
  • 9
  • 47
  • 71
  • I get an error now saying comboEdit1 doesn't have a Dispatcher method. Is this possibly because I am using a Devexpress comboBox? – 5tar-Kaster Aug 22 '13 at 09:54
  • Try "Dispatcher.BeginInvoke" instead of "comboEdit1.Dispatcher.BeginInvoke". Just FYI, Dispatcher as introduced in .NET framework 3 and up is located in the System.Windows.Threading namespace and not in System.Threading. – samar Aug 22 '13 at 09:59
1

How are you doing the multithreading? Are you creating the thread manually? Don't do that. I would recommend going with one of the following three approaches:

  1. async/await - http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx (.NET 4.5+ only)
  2. The Task Parallel Library - http://msdn.microsoft.com/en-us/library/dd460717.aspx (.NET 4.0+ only)
  3. BackgroundWorker - http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Handling the thread logic manually is of course also possible. In that case you'll probably want to look into the BeginInvoke method: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.begininvoke.aspx.

Magnus Grindal Bakken
  • 2,083
  • 1
  • 16
  • 22