Это связано с моим другим вопросом Как отменить фоновую печать.
Я пытаюсь лучше понять модель CancellationTokenSource и то, как ее использовать в разных потоках.
У меня есть главное окно (в потоке пользовательского интерфейса), где код делает:
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 (в потоке пользовательского интерфейса) я помещаю:
public CancellationTokenSource windowClosingCTS { get; set; }
С его конструктором:
// Constructor
public MainMenu()
{
readers = new List<Reader>();
CloseWindowCommand = new RelayCommand<IClosable>(this.CloseWindow);
windowClosingCTS = new CancellationTokenSource();
}
Теперь моя проблема. При закрытии MainWindow в потоке пользовательского интерфейса windowClosingCTS.Cancel() вызывает немедленный вызов делегата, зарегистрированного с помощью ct, т. е. вызывается previewWindow.Close(). Теперь это немедленно возвращает к " Если (Windows != null) с:
«Вызывающий поток не может получить доступ к этому объекту, потому что им владеет другой поток».
Так что я делаю неправильно?