在下面的示例中,当调用 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);