当前位置: 首页 > 编程语言 > C#

如何使用CancellationTokenSource在另一个线程关闭对话框?分享

时间:2023-04-10 21:25:13 C#

如何使用CancellationTokenSource关闭另一个线程的对话框?这与我的另一个问题如何取消后台打印有关。我试图更好地理解CancellationTokenSource模型以及如何跨线程边界使用它。我有一个主窗口(在UI线程上)背后的代码:publicMainWindow(){InitializeComponent();已加载+=(s,e)=>{DataContext=newMainWindowViewModel();关闭+=((MainWindowViewModel)DataContext).MainWindow_Closing;};它在关闭时正确调用CloseWindow代码:privatevoidCloseWindow(IClosablewindow){if(window!=null){windowClosingCTS.Cancel();窗口.关闭();}}通过选择菜单项,在后台线程上创建第二个窗口://打印预览publicstaticvoidPrintPreview(FixedDocumentfixeddocument,CancellationTokenct){//是否已经请求取消?如果(ct.IsCancellationRequested)ct.ThrowIfCancellationRequested();....................................//使用我的自定义文档查看器(删除了打印按钮)。varpreviewWindow=newPrintPreview(fixedDocumentSequence);//使用取消令牌注册取消过程ct.Register(()=>previewWindow.Close());previewWindow.ShowDialog();在MainWindowViewModel(在UI线程上)中,我输入:publicCancellationTokenSourcewindowClosingCTS{得到;放;}它的构造函数://ConstructorpublicMainMenu(){readers=newList();CloseWindowCommand=newRelayCommand(this.CloseWindow);windowClosingCTS=newCancellationTokenSource();现在我的问题是当在UI线程上关闭MainWindow时,windowClosingCTS.Cancel()会立即调用ct注册的delegate,即调用previewWindow.Close()。现在立即返回到“If(Windows!=null)with:”调用线程无法访问此对象,因为另一个线程拥有它。那我做错了什么?您的问题是您的预览窗口正在另一个线程上运行。当您触发取消时,您将在该线程上注册取消令牌,而不是在运行预览执行的线程上。这些情况下的黄金标准是不要使用两个UI线程。这通常很麻烦,处理它们所需的工作通常是不值得的。如果你想继续使用你的解决方案,或者如果你想从后台线程触发取消,你必须将你的关闭操作编组到你的窗口打开的线程中:ActioncloseAction=()=>previewWindow.Close();previewWindow.Dispatcher.Invoke(closeAction);您的代码有问题通过选择菜单项,在后台线程上创建第二个窗口://PrintPreviewpublicstaticvoidPrintPreview(FixedDocumentfixeddocument,CancellationTokenct){//是否已请求取消?如果(ct.IsCancellationRequested)ct.ThrowIfCancellationRequested();...................................//使用我的自定义文档查看器(删除了打印按钮)。varpreviewWindow=newPrintPreview(fixedDocumentSequence);//使用取消令牌注册取消过程ct.Register(()=>previewWindow.Close());previewWindow.ShowDialog();我想什么Task.Run(()=>PrintPreview(foo,cancel));正确的解决方案是在一个线程上执行所有操作。publicstaticTaskPrintPreview(FixedDocumentfixeddocument,CancellationTokenct){vartcs=newTaskCompletionSource();//是否已经请求取消?如果(ct.IsCancellationRequested)tcs.SetResult(false);else{//使用我的自定义文档查看器(删除了打印按钮)。varpreviewWindow=newPrintPreview(fixedDocumentSequence);//使用取消令牌注册取消过程ct.Register(()=>previewWindow.Close());previewWindow.Closed+=(o,e)=>{varresult=previewWindow.DialogResult;如果(result.HasValue)tcs.SetResult(result.Value);否则tcs.SetResult(false);}previewWindow.Show();}返回tcs.Task;}然后打上面是C#学习教程:如何使用CancellationTokenSource在另一个线程关闭对话框?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——varshouldPrint=awaitPrintPreview(foo,cancel);如果(shouldPrint)等待PrintAsync(foo);本文来自网络收藏,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: