我正在使用使用 ShowMessageAsync 方法的 MahApps Metro 对话框。在某些情况下,我会调用对话框然后取消它。我这样称呼对话框
MetroDialogSettings Settings = new MetroDialogSettings();
Settings.CancellationToken = Token;
Token.ThrowIfCancellationRequested();
await this.ShowMessageAsync("Prompt", "Prompt", MessageDialogStyle.Affirmative, Settings);
并取消
private void CancelDialog(CancellationTokenSource cts)
{
this.Dispatcher.Invoke(new Action(() => cts.Cancel()));
}
当我使用以下示例对其进行测试时,这似乎效果很好
Task.Delay(1000).ContinueWith(_=>CancelDialog(cs));
我也用过代币。ThrowIfCancellationRequested();
因为显示和取消之间存在异步性。我的问题是,如果我在演出前取消它工作正常,如果我在演出后取消它工作正常,但如果我在演出后 0~500 毫秒之间取消它,它会引发 NullReference 异常。似乎 MahApps 代码中的某些内容不正确,除非它在完全初始化之前被取消。我试图想办法锁定它,所以我只能在它初始化后取消,但我找不到方法来判断它是否准备好?
更新:
这被简化为究竟是什么失败了。以下代码抛出 NullReference 异常
CancellationTokenSource cs = new CancellationTokenSource();
MetroDialogSettings settings = new MetroDialogSettings();
settings.CancellationToken = cs.Token;
this.ShowMessageAsync("Prompt", "Prompt", MessageDialogStyle.Affirmative, settings);
this.Dispatcher.Invoke(new Action(() => cs.Cancel()));
更新 2: 这会导致异常:
CancellationTokenSource cs = new CancellationTokenSource();
MetroDialogSettings settings = new MetroDialogSettings();
settings.CancellationToken = cs.Token;
var result = this.ShowMessageAsync("Prompt", "Prompt", MessageDialogStyle.Affirmative, settings);
Task.Delay(400).ContinueWith(_ => this.Dispatcher.Invoke(new Action(() => cs.Cancel())));
虽然这不是:
CancellationTokenSource cs = new CancellationTokenSource();
MetroDialogSettings settings = new MetroDialogSettings();
settings.CancellationToken = cs.Token;
var result = this.ShowMessageAsync("Prompt", "Prompt", MessageDialogStyle.Affirmative, settings);
Task.Delay(500).ContinueWith(_ => this.Dispatcher.Invoke(new Action(() => cs.Cancel())));