В настоящее время я пишу приложение, которое будет контролировать позиционирование измерительного устройства. Из-за используемого оборудования мне нужно постоянно отслеживать текущее значение позиции при работе электродвигателя. Я пытаюсь построить класс, ответственный за это, чтобы он выполнял опрос в фоновом потоке и поднимет событие, когда будет достигнута желаемая позиция. Идея состоит в том, что опрос не будет блокировать остальную часть приложения или графический интерфейс. Я хотел использовать новый класс Threading.Task.Task, чтобы обрабатывать всю фоновую резьбу для меня.
У меня еще нет аппаратного обеспечения, но у меня есть тестовый заглушка, чтобы имитировать это поведение. Но когда я запускаю такое приложение, GUI по-прежнему блокируется. См. Упрощенный пример кода ниже (не полный и не используемый отдельный класс для управления устройством). Код имеет последовательность шагов измерения, приложение должно позиционировать, а затем измерять для каждого шага.
public partial class MeasurementForm: Form
{
private MeasurementStepsGenerator msg = new MeasurementsStepGenerator();
private IEnumerator<MeasurementStep> steps;
// actually through events from device control class
private void MeasurementStarted()
{
// update GUI
}
// actually through events from device control class
private void MeasurementFinished()
{
// store measurement data
// update GUI
BeginNextMeasurementStep();
}
private void MeasurementForm_Shown(object sender, EventArgs e)
{
steps = msg.GenerateSteps().GetEnumerator();
BeginNextMeasurementStep();
}
...
...
private void BeginNextMeasurementStep()
{
steps.MoveNext();
if (steps.Current != null)
{
MeasurementStarted();
MeasureAtPosition(steps.Current.Position);
}
else
{
// finished, update GUI
}
}
// stub method for device control (actually in seperate class)
public void MeasureAtPosition(decimal position)
{
// simulate polling
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task task = Task.Factory.StartNew(() =>
{
Thread.Sleep(sleepTime);
}, TaskCreationOptions.LongRunning)
.ContinueWith(_ =>
{
MeasurementFinished();
}, context);
}
}
Я ожидаю, что Task запустит команду Thread.Sleep в фоновом потоке, поэтому управление немедленно вернется в основной поток, и GUI не будет заблокирован. Но графический интерфейс по-прежнему блокируется. Это похоже на задачу, выполняемую по основному потоку. Любые идеи о том, что я здесь делаю неправильно?
Спасибо