c# – 如何使用CancellationTokenSource关闭另一个线程上的对话框?

c# – 如何使用CancellationTokenSource关闭另一个线程上的对话框?,第1张

概述这与我的其他问题 How to cancel background printing有关. 我试图更好地理解CancellationTokenSource模型以及如何跨线程边界使用它. 我有一个主窗口(在UI线程上)后面的代码: public MainWindow() { InitializeComponent(); Loaded 这与我的其他问题 How to cancel background printing有关.

我试图更好地理解CancellationTokenSource模型以及如何跨线程边界使用它.

我有一个主窗口(在UI线程上)后面的代码:

public MainWindow()        {            InitializeComponent();            Loaded += (s,e) => {                DataContext = new MainWindowviewmodel();                Closing += ((MainWindowviewmodel)DataContext).MainWindow_Closing;            };        }

它在关闭时正确调用CloseWindow代码:

private voID CloseWindow(IClosable window)        {            if (window != null)            {                windowClosingCTS.Cancel();                window.Close();            }        }

通过选择菜单项,在后台线程上创建第二个窗口:

// Print PrevIEw    public static voID PrintPrevIEw(Fixeddocument fixeddocument,CancellationToken ct)    {        // Was cancellation already requested?         if (ct.IsCancellationRequested)              ct.ThrowIfCancellationRequested();               ...............................             // Use my custom document vIEwer (the print button is removed).            var prevIEwWindow = new PrintPrevIEw(fixeddocumentSequence);            //Register the cancellation procedure with the cancellation token            ct.Register(() =>                    prevIEwWindow.Close()             );            prevIEwWindow.ShowDialog();        }    }

在MainWindowviewmodel(在UI线程上),我把:

public CancellationTokenSource windowClosingCTS { get; set; }

其构造函数为:

// Constructor    public MainMenu()    {        readers = new List<Reader>();        CloseWindowCommand = new RelayCommand<IClosable>(this.CloseWindow);        windowClosingCTS = new CancellationTokenSource();    }

现在我的问题.当关闭UI线程上的MainWindow时,windowClosingCTS.Cancel()会立即调用使用ct注册的委托,即调用prevIEwWindow.Close().这现在立即返回到“If(windows!= null):

“The calling thread cannot access this object because a different
thread owns it.”

那么我做错了什么?

解决方法 您的问题是您的预览窗口在另一个线程上运行.当您触发取消时,您在该线程上执行取消令牌的注册 *** 作,而不是在运行预览的线程上执行.

这些情况下的黄金标准是不使用两个UI线程.这通常会带来麻烦,而处理它们所需的工作通常是不值得的.

如果您想继续使用您的解决方案,或者如果您想从后台线程触发取消,则必须将您的关闭 *** 作编组到您的窗口打开的线程中:

Action closeAction = () => prevIEwWindow.Close();prevIEwWindow.dispatcher.Invoke(closeAction);
总结

以上是内存溢出为你收集整理的c# – 如何使用CancellationTokenSource关闭另一个线程上的对话框?全部内容,希望文章能够帮你解决c# – 如何使用CancellationTokenSource关闭另一个线程上的对话框?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1249141.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存