2013-08-22 14 views
-2

我的问题很简单,我的SQL查询需要2分钟才能完成,我不能让我的应用程序在尝试获取所有数据时被冻结。我尝试了多线程,但是我一直在遇到一个我很确定你会认识的错误。我的代码就在这个下面。在线程中加载数据

跨线程操作无效:从其创建的线程以外的线程访问的控件'labelEdit1'。

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(); 
} 

如果有更好的方法来做到这一点,那么请让我知道,我需要的是为应用程序不会冻结起来,这些数据取得装入comboEdit。我也知道SQL语句可以优化,但这不是这个问题的关键,所以请不要提示它。

+0

您是否对交叉线程异常做过任何研究?这个问题的第一个相关问题有标题“跨线程操作无效:控制访问从一个线程以外的线程创建它”... –

+0

http://stackoverflow.com/questions/142003/cross -thread-operation-not-valid-control-accessible-from-a-thread-other-than-the-rq = 1 –

+0

-1缺少研究 –

回答

1

您需要在这里使用调度程序。这是因为你不能从另一个线程访问UI线程拥有的控件。检查这个链接here。我没有检查过这个编译错误,但是这个应该会对你做一些小小的修改。

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(); 
} 
+0

现在出现错误,说comboEdit1没有Dispatcher方法。这可能是因为我使用了Devexpress组合框? –

+0

尝试使用“Dispatcher.BeginInvoke”而不是“comboEdit1.Dispatcher.BeginInvoke”。只是FYI,在.NET Framework 3和更高版本中引入的Dispatcher位于System.Windows.Threading命名空间中,而不是System.Threading中。 – samar

1

你是怎么做多线程的?您是否手动创建线程?不要这样做。我建议用以下三种方法之一去:

  1. async/await - http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx(.NET 4.5 +只)
  2. 任务并行库 - http://msdn.microsoft.com/en-us/library/dd460717.aspx(.NET 4.0 +只)
  3. BackgroundWorker - http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

手动处理线程逻辑当然也是可以的。在这种情况下,您可能需要查看BeginInvoke方法:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.begininvoke.aspx