Думаю, я бы передал список параметров, значений и делегатов на BackgroundWorker
. Таким образом, вы можете написать код обратного присваивания «синхронно», но отложить выполнение до тех пор, пока значения не будут фактически получены.
Начните с класса «request», который выглядит примерно так:
class ParameterUpdate
{
public ParameterUpdate(string name, string value, Action<string> callback)
{
this.Name = name;
this.Value = value;
this.Callback = callback;
}
public string Name { get; private set; }
public string Value { get; set; }
public Action<string> Callback { get; private set; }
}
Затем напишите свой асинхронный код, чтобы использовать это:
private void bwUpdateParameters_DoWork(object sender, DoWorkEventArgs e)
{
var updates = (IEnumerable<ParameterUpdate>)e.Argument;
foreach (var update in updates)
{
WriteDeviceParameter(update.Name, update.Value);
update.Value = ReadDeviceParameter(update.Name);
}
e.Result = updates;
}
private void bwUpdateParameters_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
var updates = (IEnumerable<ParameterUpdate>)e.Argument;
foreach (var update in updates)
{
if (update.Callback != null)
{
update.Callback(update.Value);
}
}
}
Вот как бы вы запустили обновление. Допустим, у вас есть группа полей-членов, которые вы хотите обновить, добавив фактические значения используемых параметров:
// Members of the Form/Control class
private string bandwidth;
private string inputAttenuation;
private string averaging;
// Later on, in your "update" method
var updates = new List<ParameterUpdate>
{
new ParameterUpdate("Bandwidth", "3000", v => bandwidth = v),
new ParameterUpdate("InputAttenuation", "10", v => inputAttenuation = v),
new ParameterUpdate("Averaging", "Logarithmic", v => averaging = v)
};
bwUpdateParameters.RunWorkerAsync(updates);
Это все, что тебе нужно сделать. Вся фактическая работа выполняется в фоновом режиме, но вы пишете простые операторы присваивания переменных, как если бы они были на переднем плане. Код является коротким, простым и полностью поточно-ориентированным, поскольку фактические назначения выполняются в событии RunWorkerCompleted
.
Если вам нужно сделать больше, чем, например, элементы управления обновлением в дополнение к переменным, это очень просто, вы можете поместить все, что вы хотите, для обратного вызова, т.е.
new ParameterUpdate("Bandwidth", "3000", v =>
{
bandwidth = v;
txtBandwidth.Text = v;
})
Опять же, это будет работать, потому что на самом деле не выполняется, пока работа не будет завершена.