Есть много различных способов, чтобы предотвратить форму от быть заморожены.
Например, вы можете загрузить свои данные, как это:
private async void Form_Load(object sender, EventArgs e)
{
//do some initializations
await LoadData();
//do some other initializations that you need to perform.
}
private async Task LoadData()
{
//Load your data here
//For example
FTPUtility obj = new FTPUtility();
dataGridViewRequest.DataSource = obj.ListRequestFiles();
}
Этот способ при запуске формы, команды выполняются в последовательности, вы писали в то время как интерфейс реагирует, и вы не будете сталкиваться с общими трудностями использования BackgroundWorker
или потоки, такие как исключения перекрестной резьбы.
Ключевым моментом является использование async/wait. Для более подробной информации читайте Asynchronous Programming with Async and Await
Помните, что таким образом, каждый, где вы хотите позвонить LoadData, вы должны назвать это таким образом:
await LoadData();
И метод, который вы пишете этот код, должен быть асинхронной:
private async void RefreshButton_Click(object sender, EventArgs e)
{
await LoadData();
}
EDIT для .Net 4.0
Для .Net 4.0 вы можете использовать как Task.Run
, так и BackgroundWorker
. Я рекомендую Task.Run
, потому что он более прост и читаем.
Обратите внимание, что операция поперечной резьбы исключается при доступе к элементам пользовательского интерфейса из другого потока, кроме UI. В таких ситуациях вместо этого вы должны использовать this.Invoke(new Action(()=>{/*Access UI Here*/}));
. И никогда не ставьте трудоемкую задачу в свою часть invoke.
BackgroundWorker подход:
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
//If you put some code here for example MessageBox.Show("");
//The code will immadiately run and don't wait for worker to complete the task.
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.LoadData();
}
public void LoadData()
{
var ftp = new FtpUtility();
var data = ftp.ListRequestFiles();
this.Invoke(new Action(() =>
{
//Setup columns and other UI stuff
//Set datasource of grid
this.dataGridView1.DataSource = data;
}));
}
- Помните везде вы раньше использовали
LoadData
, теперь вы должны использовать backgroundWorker1.RunWorkerAsync();
вместо этого.
- Если вы хотите выполнить работу после того, как работник выполнит задачу, поместите свое задание в
backgroundWorker1_RunWorkerCompleted
или в Invoke
часть LoadData
.
Task.Run подход
private void Form1_Load(object sender, EventArgs e)
{
Task.Run(() =>
{
LoadData();
})
.ContinueWith(x =>
{
//You can put codes you want run after LoadData completed here
//If you access the UI here, you should use Invoke
});
//If you put some code here for example MessageBox.Show("");
//The code will immadiately run and don't wait for worker to complete the task.
}
public void LoadData()
{
var ftp = new FtpUtility();
var data = ftp.ListRequestFiles();
this.Invoke(new Action(() =>
{
//Setup columns and other UI stuff
//Set datasource of grid
this.dataGridView1.DataSource = data;
}));
}
- Помните везде вы раньше использовали
LoadData
, теперь вы должны использовать Task.Run(()=>{LoadData();});
вместо этого.
- Если вы хотите сделать работу после завершения
LoadData
, оставьте свою работу в ContinueWith
или в Invoke
часть LoadData
.
Что вы делаете (= попытка изменить элемент GUI из потока BackgroundWorker) не может быть выполнена. Вам лучше прочитать что-нибудь о «BackgroundWorker»/многопоточности в C# /. NET, потому что ваши идеи не совсем понятны. – varocarbas
@varocarbas Я пытаюсь получить файлы из ftp на моем локальном приложении Windows datagridview, когда я загружаю данные, требуется слишком много времени, поэтому я хочу сначала загрузить основную форму, а затем через секунду файлы будут отображаться в datagridview. –
Как объяснялось в моем предыдущем комментарии: ваш код делает что-то, что доказывает вам абсолютную нехватку знаний относительно «BackgroundWorker» и основных идей (т. Е. Многопоточности). Улучшите свои знания на обоих фронтах, вместо того, чтобы делать слепые тесты и жаловаться на каждую отдельную проблему, которую вы видите. – varocarbas