阻止从不同线程启动 WPF 对话框
Blocking launch of WPF Dialog from a different thread
我们想在主 window 上创建并启动一个 模态对话框 框。这个过程是从不同的线程启动的——出于某种原因。这个不同的线程调用 execute 方法 - 并且必须被阻塞直到对话框关闭。问题是——如何?在此代码上,执行不会被阻止。 Join() 调用也没有按预期工作。
public void Execute()
{
Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
// newWindowThread.Join();
}
private void ThreadStartingPoint()
{
this.ParameterDialog = new ParameterDialog();
this.ParameterDialog.ShowDialog();
System.Windows.Threading.Dispatcher.Run();
}
知道如何实现这种行为吗?提前致谢!
在不知道整个设置如何工作的情况下,这里是一个快速示例,说明如何利用 Dispatcher 从单独的线程与 UI 层进行交互。我使用 Microsoft wpf 库 here 中的示例作为我的起点。我去掉了一些不适用的代码。
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public delegate void NextPrimeDelegate();
private bool _continueCalculating;
private Action MyCallback = () =>
{
//****Carry out your Code (Execute) Here****
var myPopup = new PopUp();
myPopup.ShowDialog();
};
public MainWindow()
{
InitializeComponent();
}
private void StartOrStop(object sender, EventArgs e)
{
if (_continueCalculating)
{
_continueCalculating = false;
startStopButton.Content = "Resume";
}
else
{
_continueCalculating = true;
startStopButton.Content = "Stop";
startStopButton.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new NextPrimeDelegate(MyCallback));
}
}
}
MyPopUp.xaml
<Window x:Class="SingleThreadedApplication.PopUp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SingleThreadedApplication"
mc:Ignorable="d"
Title="PopUp" Height="200" Width="300">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Close"
Executed="CloseCommandHandler"/>
</Window.CommandBindings>
<Grid>
<TextBlock Text="My Popup" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Content="Close" HorizontalAlignment="Right" VerticalAlignment="Bottom" Command="ApplicationCommands.Close"/>
</Grid>
将此方法添加到 PopUp.xaml.cs
private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
this.Close();
}
这有望为您提供一个起点,让您通过不同的线程与 UI 层进行交互。
您应该在对话框 window 关闭时关闭调度程序:
public void Execute()
{
Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
newWindowThread.Join();
}
private void ThreadStartingPoint()
{
this.ParameterDialog = new ParameterDialog();
this.ParameterDialog.Closed += ParameterDialog_Closed;
this.ParameterDialog.ShowDialog();
System.Windows.Threading.Dispatcher.Run();
}
private void ParameterDialog_Closed(object sender, EventArgs e)
{
this.ParameterDialog.Closed -= ParameterDialog_Closed;
Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
}
我们想在主 window 上创建并启动一个 模态对话框 框。这个过程是从不同的线程启动的——出于某种原因。这个不同的线程调用 execute 方法 - 并且必须被阻塞直到对话框关闭。问题是——如何?在此代码上,执行不会被阻止。 Join() 调用也没有按预期工作。
public void Execute()
{
Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
// newWindowThread.Join();
}
private void ThreadStartingPoint()
{
this.ParameterDialog = new ParameterDialog();
this.ParameterDialog.ShowDialog();
System.Windows.Threading.Dispatcher.Run();
}
知道如何实现这种行为吗?提前致谢!
在不知道整个设置如何工作的情况下,这里是一个快速示例,说明如何利用 Dispatcher 从单独的线程与 UI 层进行交互。我使用 Microsoft wpf 库 here 中的示例作为我的起点。我去掉了一些不适用的代码。
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public delegate void NextPrimeDelegate();
private bool _continueCalculating;
private Action MyCallback = () =>
{
//****Carry out your Code (Execute) Here****
var myPopup = new PopUp();
myPopup.ShowDialog();
};
public MainWindow()
{
InitializeComponent();
}
private void StartOrStop(object sender, EventArgs e)
{
if (_continueCalculating)
{
_continueCalculating = false;
startStopButton.Content = "Resume";
}
else
{
_continueCalculating = true;
startStopButton.Content = "Stop";
startStopButton.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new NextPrimeDelegate(MyCallback));
}
}
}
MyPopUp.xaml
<Window x:Class="SingleThreadedApplication.PopUp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SingleThreadedApplication"
mc:Ignorable="d"
Title="PopUp" Height="200" Width="300">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Close"
Executed="CloseCommandHandler"/>
</Window.CommandBindings>
<Grid>
<TextBlock Text="My Popup" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Content="Close" HorizontalAlignment="Right" VerticalAlignment="Bottom" Command="ApplicationCommands.Close"/>
</Grid>
将此方法添加到 PopUp.xaml.cs
private void CloseCommandHandler(object sender, ExecutedRoutedEventArgs e)
{
this.Close();
}
这有望为您提供一个起点,让您通过不同的线程与 UI 层进行交互。
您应该在对话框 window 关闭时关闭调度程序:
public void Execute()
{
Thread newWindowThread = new Thread(new ThreadStart(ThreadStartingPoint));
newWindowThread.SetApartmentState(ApartmentState.STA);
newWindowThread.IsBackground = true;
newWindowThread.Start();
newWindowThread.Join();
}
private void ThreadStartingPoint()
{
this.ParameterDialog = new ParameterDialog();
this.ParameterDialog.Closed += ParameterDialog_Closed;
this.ParameterDialog.ShowDialog();
System.Windows.Threading.Dispatcher.Run();
}
private void ParameterDialog_Closed(object sender, EventArgs e)
{
this.ParameterDialog.Closed -= ParameterDialog_Closed;
Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
}