在下面的示例中,当调用Tag1_changed和Tag2_changed方法时,它们需要调用表单来更新控件,否则抛出异常。但是,当使用lambda方法作为回调参数时,this.InvokeRequired的计算结果为true,但控件仍然更新,即使没有使用表单的MethodInvoker,也不会抛出异常。为什么(pnlHeartbeat.BackColor)语句在执行时不会抛出异常?
private void BtnSubscribe_Click(object sender, EventArgs e)
{
var task = AppGlobals.opc.SubscribeToTagAsync("k_Tag1", Tag1_changed);
task = AppGlobals.opc.SubscribeToTagAsync("k_Tag2", Tag2_changed);
task = AppGlobals.opc.SubscribeToTagAsync("k_Heartbeat", (tagname, tag) =>
{
try
{
bool ir = this.InvokeRequired; //this is always true
pnlHeartbeat.BackColor = tag.Value.ToBooleanOrDefault(false) ? System.Drawing.Color.Green : System.Drawing.Color.Red; //value updates fine without exception
}
catch (Exception ex)
{
string exm = ex.Message; //never gets here even though InvokeRequired is true
}
});
}
private void Tag1_changed(string tagname, DataValue tag)
{
this.BeginInvoke(new MethodInvoker(() =>
{
lblTag1Value.Text = tag.Value.ToString();
}));
}
private void Tag2_changed(string tagname, DataValue tag)
{
this.BeginInvoke(new MethodInvoker(() =>
{
lblTag2Value.Text = tag.Value.ToString();
}));
}
SubscibeToTagAsync方法签名是:
public async Task SubscribeToTagAsync(string tagname, Action<string, DataValue> callback)
回调Action存储在OnChange属性中,最终以下列方式执行:
this.Tags[tag.Key].OnChange?.Invoke(tag.Key, mon.Value);