【问题标题】:Load Data and show a splash screen during that加载数据并在此期间显示启动画面
【发布时间】:2010-12-02 03:19:25
【问题描述】:

我必须从 db4o 数据库中加载一些数据,这在我的应用程序启动时需要 1 或 2 秒,其余的必须等待,因为首先必须加载所有数据。在自己的线程中执行此操作将意味着其余部分必须等待线程完成。我想在加载数据期间做一个闪屏或其他什么也需要一个自己的线程,对吗?你会怎么做?

我正在使用 csharp、.net 3.5 和 winforms

【问题讨论】:

  • 我认为您需要说明您的应用程序是用什么语言编写的(而不仅仅是哪个数据库)。
  • MusiGenesis,不仅仅是“语言”,它会导致“我在 C# 中有一个 ListBox”的含糊不清。
  • @Henk:嗯,kai 说的是“c#、.net 和 WinForms”,这就是我们需要知道的全部内容。

标签: c# .net winforms .net-3.5 splash-screen


【解决方案1】:

在启动时显示启动画面很容易。在应用程序的 Main() 方法中(在 Program.cs 中),在 Application.Run(...) 行之前放置类似这样的内容:

SplashForm splashy = new SplashForm();
splashy.Show();
Application.Run(new MainForm(splashy));

修改主窗体的代码和构造函数,使其看起来像这样:

private SplashForm _splashy;
public MainForm(SplashForm splashy)
{
    _splashy = splashy;
    InitializeComponent();
}

然后在 MainForm 的 Load 事件(大概包含数据库代码)的末尾,输入以下代码:

_splashy.Close();
_splashy.Dispose();

如果您选择使用单独的 Thread 或 BackgroundWorker 进行数据库访问,那么您实际上并不需要启动屏幕,而是需要在 BackgroundWorker 执行其操作时出现某种进度指示器表单。这与我在这里的回答不同。

【讨论】:

  • 从设计的角度来看,没有必要给 MainForm 增加管理 SplashForm 的负担。您可以使用单独的线程或利用 WinForms.Timer 对 MessageLoop 的依赖。
  • @Henk:或者我可以继续并通过管理 SplashForm 来“负担” MainForm,因为它是执行一项非常小的任务的非常简单的方法。谈过早的优化 ...
【解决方案2】:

一种方法,但可能是更好的方法。创建一个新的对话框表单,它将作为您的进度窗口/启动屏幕。将位图或其他任何东西作为唯一的项目。从主程序实例化对话框。覆盖进度表单的 Load 事件,并从那里启动新线程,该线程将执行后台处理工作以加载数据。这样您就可以从您的主应用程序中调用 ShowDialog。

如果您使用 System.ComponentModel.BackgroundWorker,那么您可以轻松地为线程完成连接事件并从该事件中自动退出对话框。控制权返回给调用应用程序,您就完成了。

我以前在应用程序中做过这种事情,它工作正常,但我确信这是一种新手方法。以下是启动后台线程的表单中加载事件的示例代码(在我的情况下,我正在打开和解析大文件):

 private void FileThreadStatusDialog_Load(object sender, EventArgs e)
 {
Cursor = Cursors.WaitCursor;

if (m_OpenMode)
{
    this.Text = "Opening...";
    StatusText.Text = m_FileName;
    FileThread = new BackgroundWorker();
    FileThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(FileThread_RunWorkerCompleted);
    FileThread.DoWork += new DoWorkEventHandler(FileOpenThread_DoWork);
    FileThread.WorkerSupportsCancellation = false;
    FileThread.RunWorkerAsync();
}
else
{
    this.Text = "Saving...";
    StatusText.Text = m_FileName;
    FileThread = new BackgroundWorker();
    FileThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(FileThread_RunWorkerCompleted);
    FileThread.DoWork += new DoWorkEventHandler(FileSaveThread_DoWork);
    FileThread.WorkerSupportsCancellation = false;
    FileThread.RunWorkerAsync();
}

}

下面是工作完成方法的样子,它存在于表单中:

private void FileThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    FileThread = null;
        DialogResult = DialogResult.OK;
        Close();
}

这是我从主对话框打开进度对话框的方法:

FileThreadStatusDialog thread = new FileThreadStatusDialog(m_Engine, dlg.FileName, true);
if (thread.ShowDialog(this) == DialogResult.OK)
{
        m_Engine = thread.Engine;
    FillTree();
}

【讨论】:

    【解决方案3】:

    人们可能想通过添加来强制在 MusiGenesis 的答案中画出水花

    Application.DoEvents();
    

    紧接着

    splashy.Show();
    

    【讨论】:

      猜你喜欢
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 2010-11-21
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多