У меня запущен длинный запрос данных, пользователь должен видеть прогресс.
Итак, я наткнулся на BackgroundWorker , мне показалось, что все просто, и я попытался внедрить его в свое приложение. С некоторым тестированием он не отвечал, поэтому во время исследования я обнаружил, что при использовании шаблона проектирования Model View Presenter необходимо сделать это по-другому. При исследовании я наткнулся на этот ответ .
Итак, я попытался реализовать это:
IView
public interface IChecks : IView
{
void getDataSets(DataSet ds);
event EventHandler CheckActive;
string sqlQuery { get; set; }
int checkNumber { get; set; }
void ShowProgress(int progressPercentage);
bool isBusy { get; set; }
event EventHandler StartTimeConsumingJob;
}
View
private void CheckButton_Click(object sender, EventArgs e)
{
//Execute 5 checks, with an number given so the right DataGridViews get filled.
if (Check1.Checked == true)
{
checkNumber = 1;
sqlQuery = "SELECT DISTINCT e.[BUO] ,e.[Method] ,[EANLocationCode] ,[Customer] FROM [Navision].[dbo].[InventorySales] e WHERE NOT EXISTS (SELECT c.BUO, c.CustomerCode FROM Customers c WHERE c.BUO = e.BUO AND c.CustomerCode = CustomerNo) ORDER BY BUO, Method, LocationCode";
StartTimeConsumingJob(this, EventArgs.Empty);
}
}
public void getDataSets(DataSet ds)
{
if(checkNumber == 1)
{
dataGridView1.DataSource = ds.Tables[0];
Check1Label.Text = ds.Tables[0].Rows.Count.ToString();
Check1Label.Visible = true;
}
}
Presenter
private BackgroundWorker _bw;
public ChecksPresenter(IChecks view) : base(view)
{
View.CheckActive += View_CheckActive;
View.StartTimeConsumingJob += View_StartTimeConsumingJob;
_bw = new BackgroundWorker();
_bw.WorkerReportsProgress = true;
_bw.WorkerSupportsCancellation = true;
_bw.DoWork += new DoWorkEventHandler(_bw_DoWork);
_bw.ProgressChanged += new ProgressChangedEventHandler(_bw_ProgressChanged);
_bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bw_Completed);
}
void View_CheckActive(object sender, EventArgs e)
{
View.getDataSets(CheckModel.dt(View.sqlQuery));
//This function returns database data.
}
public void View_StartTimeConsumingJob(object sender, EventArgs e)
{
_bw.RunWorkerAsync();
}
private void _bw_DoWork(object sender, DoWorkEventArgs e)
{
View.isBusy = true;
View.getDataSets(CheckModel.dt(View.sqlQuery));
}
private void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
View.ShowProgress(e.ProgressPercentage);
}
private void _bw_Completed(object sender, RunWorkerCompletedEventArgs e)
{
}
}
Я пропустил некоторые вещи, потому что я пытался сначала позволить ему работать. Он не работал и не отвечал, он зависал только при нажатии кнопки 2 раза (но это имеет смысл, потому что я не реализовал if if в событии CheckButton_click).
Мой вопрос:
Чего мне не хватает, чтобы оно не отвечало? Это больше похоже на фактическое подключение к базе данных не происходит. Он работает без фонового работника, но мне хотелось бы иметь больше ясности при выполнении запроса.