2009-09-28 2 views
3

Мне нужно загрузить некоторые данные из базы данных db4o, которая занимает 1 или 2 секунды при запуске моего приложения, остальная часть должна ждать, потому что в первую очередь данные должны быть загружен. сделать это в собственном потоке, означало бы, что остальное должно ждать завершения финишной обработки. Я бы хотел сделать заставку или что-то во время загрузки данных, для чего также нужен собственный поток, не так ли? как бы вы это сделали?Загрузить данные и показать заставку во время этого

Я использую Csharp, .NET 3.5 и WinForms

+2

Я думаю, что вы должны сказать, что язык приложение написано в (не только какие база данных). – MusiGenesis

+0

извините, сделал некоторые изменения;) – Kai

+0

MusiGenesis, а не только «язык», что приводит к неопределенности «У меня есть ListBox в C#». –

ответ

5

Показать заставку при запуске легко. В методе вашего приложения 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(); 
} 

Затем в конце события Load вашего MainForm (который предположительно содержит коды базы данных), поместите этот код:

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

Если вы решили сделать свой доступ к базе данных с отдельным Thread или BackgroundWorker, тогда вам действительно не нужен всплеск, так как вам нужна какая-то форма индикатора прогресса, которая появляется, когда BackgroundWorker делает свою работу. Это будет сделано иначе, чем мой ответ здесь.

+0

С точки зрения дизайна, нет необходимости обременять MainForm управлением SplashForm. Вы можете использовать отдельный поток или использовать зависимость WinForms.Timer от MessageLoop. –

+1

@Henk: или я мог бы просто пойти и «обременять» MainForm управлением SplashForm, так как это невероятно простой способ выполнить невероятно незначительную задачу. Расскажите о * преждевременной оптимизации * ... – MusiGenesis

+0

@MusicGenesis: Это смешно прямо здесь. – user1481183

1

Один путь, вероятно, более эффективные способы, хотя. Создайте новую диалоговую форму, которая будет вашим оконным окном/заставкой. Бросьте растровое изображение или что-то еще на нем как единственный предмет. Создайте диалог из основной программы. Переопределите событие загрузки для формы выполнения и оттуда запустите новый поток, который будет выполнять фоновые обработки для загрузки данных. Таким образом вы можете просто вызвать ShowDialog из основного приложения.

Если вы используете System.ComponentModel.BackgroundWorker, то вы можете легко подключить события к тому, когда поток завершится и автоматически завершит диалог с этого события. Элемент управления возвращается обратно в вызывающее приложение, и все готово.

Я делал это в приложении раньше, и он работает нормально, но я уверен, что это новичок. Вот пример кода из события Load в форме, которая запускает фоновый поток (в моем случае, я открываю и анализ больших файлов):

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

Можно хотеть, чтобы заставить рисунок показной в ответ MusiGenesis', добавив

Application.DoEvents(); 

сразу после

splashy.Show(); 
Смежные вопросы