Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WinApp窗体在加载事件期间加载太多数据_C#_Winforms_Backgroundworker - Fatal编程技术网

C# WinApp窗体在加载事件期间加载太多数据

C# WinApp窗体在加载事件期间加载太多数据,c#,winforms,backgroundworker,C#,Winforms,Backgroundworker,我有一个表单正在从SQLServer加载大量数据。下面的代码将提供一个很好的提示: private void BranchCenter_Load(object sender, EventArgs e) { //Combo boxes: LoadCities(); LoadCoordinators(); LoadComputerSystems(); //Actual entity LoadBranch(); } private void LoadCities() {

我有一个表单正在从SQLServer加载大量数据。下面的代码将提供一个很好的提示:

private void BranchCenter_Load(object sender, EventArgs e) {
  //Combo boxes:
  LoadCities();
  LoadCoordinators();
  LoadComputerSystems();

  //Actual entity
  LoadBranch();
}

private void LoadCities() {
  //LINQ2SQL to load data. ~5000 records.
}

private void LoadCoordinators() {
  //LINQ2SQL to load data. ~50 records.
}

private void LoadComputerSystems() {
  //LINQ2SQL to load data. ~550 records.
}

private void LoadBranch() {
  LoadBranchInit();
  LoadBranchDetails();
  LoadBranchTimings();
  LoadBranchServices();
  LoadBranchLocumsHistory();
  LoadBranchJobs();
  LoadBranchNotes();
}

private void LoadBranchInit() {
  //LINQ2SQL to load the Branch object based upon the Branch ID
}

private void LoadBranchDetails() {
  //LINQ2SQL to load basic branch stuff. 38 fields. Mixed editors.
}

private void LoadBranchTimings() {
  //LINQ2SQL to load timings info into 80 date-time controls
}

private void LoadBranchServices() {
  //LINQ2SQL to load services offered at branch info into 20 check-boxes controls
}

private void LoadBranchLocumsHistory() {
  //LINQ2SQL to load branch history info into grid control. Always increasing # of rows :(
}

private void LoadBranchJobs() {
  //LINQ2SQL to load branch jobs info into grid control. Always increasing # of rows :( 
}

private void LoadBranchNotes() {
  //LINQ2SQL to load branch notes info into grid control
}
UI是一个带有选项卡控件的表单。上面的每个细节都会进入一个选项卡页面。我需要加载和显示的形式给用户尽快。一旦表单显示出来,我需要启动一系列后台工作程序来获取每个页面的数据

我一直试图搞乱后台工作人员,但无法理解它的用法。最后,我收到了这样一条消息:“不同的线程试图访问主线程上的控制权…或者类似的东西…”

理想的情况是在每个选项卡上都有一个加载数据的进度条,并且在相应的后台工作人员完成后,该选项卡就可以交互


有什么策略或建议吗?感谢阅读。

如果每种类型的数据仅显示在一个页面上,我会移动代码,以便在第一次加载每个选项卡页面时加载每种相应类型的数据。这样,数据加载工作将在更长的时间内分配,如果用户在会话期间没有导航到所有选项卡,则可能完全避免


加载页面时,可以使用
BackgroundWorker
或任何其他异步机制。在选项卡页面中,可以有两个面板控件。一个包含页面的UI,并且在加载表单时具有
Visible=false
,另一个包含带有文本“Loading,please wait…”的标签。为页面加载数据并更新UI时,在两个面板上切换可见性以显示UI。这样,表单在加载数据时仍然会有响应,而且由于一次只加载一页数据,加载时间应该相当短

这里的问题是BackgroundWorker的DoWork方法无法接触GUI

它必须使用
BackgroundWorker.ReportProgress(int-progress,object-state)
在GUI线程上调用一个可以自由更新GUI的方法


这里最重要的一点是,GUI控件只能从GUI线程本身更新,否则程序中会到处出现随机异常。

理想的解决方案是不在表单加载事件中加载数据

让表单正确、完整地加载,以便UI呈现完成

之后,您可以在任何需要的地方显示进度条,并且可以执行实际的数据加载(同步或异步)


如果你不需要同时加载所有的东西,我也会考虑只在第一次访问标签时加载数据,所以如果用户从来没有点击最后一个标签,例如,你没有为它加载任何东西。

你不能从UI线程之外的任何其他线程中使用UI。这就是你错误的根源。如果您想了解有关如何从不同线程正确更新UI元素的更多信息,则需要使用Invoke。关于堆栈溢出的问题可能会帮助您解决。

为了解决后台工作线程遇到的问题,听起来您可能试图从线程本身访问UI组件。要从非UI线程执行此操作,您需要使用Control.Invoke,而不是尝试直接访问组件。

是的,BackgroundWorker非常适合这样做

我认为你做得不对,因为你想在嫁妆活动中改变你的形式

但是,您应该只在e中收集此事件的结果。该事件的结果


然后在RunWorkerCompleted中,您可以使用其e.Results更改表单。

为每个选项卡创建一个BackgroundWorker。在窗体的加载事件中,禁用所有选项卡,并为每个后台工作进程调用RunWorkerAsync()方法

在每个DoWork事件处理程序中,将关联选项卡页所需的数据从数据库加载到数据表中,并将DoWorkEventArgs的Result属性设置为数据表

注意:在DoWork事件处理程序中,您不应该更新任何UI控件,因为它在不同的线程中运行。您应该只从数据库中检索数据并设置Result属性


在RunWorkerCompletedEventHandler中,您可以通过获取RunWorkerCompletedEventArgs的Result属性来访问在DoWork事件处理程序中检索的数据表。然后,您可以相应地设置UI控件的属性,然后启用与当前后台工作程序关联的选项卡页。

好的。在很短的时间内做出了巨大的反应。我喜欢这个地方。从二环跳下,我与他面对面。这也是一个好的替代品吗?找不到关于如何在我的场景中使用Rx的教程。

TabControl已经进行了延迟加载


帮你自己一个忙,把每个标签的内容放在一个用户控件上。

好的,我面临一个新的情况。我转到VisualStudio2010,遇到Task.Factory.StartNew(()=>myMethod())

这就是我到目前为止所做的:

private void LoadLocum() {
    var TaskInit = Task.Factory.StartNew(() => LoadLocumInit());
    TaskInit.Wait();

    var TaskDetails = Task.Factory.StartNew(() => LoadLocumDetails());
    TaskDetails.Wait();

    var TaskQualifications = Task.Factory.StartNew(() => LoadLocumQualifications());
    //Enable Qualification TabPage automatically whenever TaskQualifications is complete

    Parallel.Invoke(
        () => LoadLocumComputerSystems(), 
        () => LoadLocumOtherInfo(), 
        () => LoadLocumEmergencyContacts(), 
        () => LoadLocumDistanceRates(), 
        () => LoadLocumDocuments(), 
        () => LoadLocumNotes(), 
        () => LoadLocumBannedStatus()
    );

}

前两个步骤(任务)至关重要。现在,选项卡的选项卡页被禁用。我需要在完成相关任务的基础上启用它们。我可以找到一个要订阅的事件,表明某项任务是否完成。

数据太多,无法在e.Result中正常运行。。。但是我只能回来一次,实际上我尝试了变形。为什么太多了?若要异步获取该数据,无论您做什么,都必须在某个变量的非GUI线程上收集该数据,然后调用UI线程并用数据更新UI。BackgroundWorker实际上就是这么做的。如果使用线程,您可以更加灵活,但可能不值得费心。因此,我不确定我是否尝试过BackgroundWorker处理一些真正的大型数据集,但我看不到任何不好的情况会发生,除非它们对于计算机内存来说太大。“TabControl已经进行了延迟加载。”。。找不到