Я делаю приложение C# для мониторинга некоторых вещей в SQL. Я использую фонового работника для сбора данных SQL, а затем создаю несколько диаграмм на основе данных. Довольно простой. Однако в этом есть одна неприятная вещь. Использование Thread.Sleep в рабочем состоянии полностью блокирует пользовательский интерфейс. Нет загрузки gif, входы не регистрируются, нада. Это очень странное поведение для меня, потому что из того, что я читал о случаях использования фонового рабочего, он должен работать на своем потоке, ПОЛНОСТЬЮ отдельно от пользовательского интерфейса. Так что же дает? Что я могу использовать вместо этого? Вот мой код фона рабочий:C# appliction background worker - Thread.Sleep stops UI
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (CollectionCanceled)
return;
//Get data from SQL DB
var jobService = _serviceFactory.CreateJobService();
var jobs = jobService.GetAllJobs(true);
backgroundWorker1.ReportProgress(0, jobs);
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var allJobs = e.UserState as IList<Job>;
if (allJobs == null || CollectionCanceled)
return;
//Build collection
Dictionary<string, Dictionary<string, int>> details = new Dictionary<string, Dictionary<string, int>>();
foreach (var job in allJobs)
{
var overViewKey = job.State.ToString();
var detailKey = string.Format("{0} ({1})", job.Name, job.Type);
if (!details.ContainsKey(overViewKey))
details.Add(overViewKey, new Dictionary<string, int>());
if (!details[overViewKey].ContainsKey(detailKey))
details[overViewKey].Add(detailKey, 0);
details[overViewKey][detailKey]++;
}
//Build charts
Overview.Series.Clear();
Detailed.Series.Clear();
Overview.Series.Add("Jobs");
Detailed.Series.Add("Jobs");
foreach (var runniningOrEnqueued in details)
{
Overview.Series["Jobs"].Points.AddXY(runniningOrEnqueued.Key, runniningOrEnqueued.Value.Count);
foreach (var jobDetail in runniningOrEnqueued.Value)
Detailed.Series["Jobs"].Points.AddXY(jobDetail.Key, jobDetail.Value);
}
//Stop for however many secs the user specified
Thread.Sleep((int)TimeSpan.FromSeconds(WaitTimer).TotalMilliseconds);
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!CollectionCanceled)
{
ExecuteBackGroundWork();
}
else
{
CollectionCanceled = false;
}
}
private void ExecuteBackGroundWork()
{
backgroundWorker1.RunWorkerAsync();
}
Причина, по которой BackgroundWorker_ProgressChanged происходит в потоке пользовательского интерфейса, заключается в том, что вы можете обновлять элементы управления в пользовательском интерфейсе. –
duh! Теперь я чувствую себя глупо. Спасибо, что помогли приложению n00b. Отметьте как ответ, как только я смогу. – user2326106