本文主要是介绍WPF Dispatcher.FromThread,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Dispatcher.FromThread 方法可以从线程中获得 Dispatcher ,如果此线程中操作了UI相关的对象,如窗体,控件等,那么它的返回值将不为null, 否则为null.
举个例子:
新建一个wpf应用:默认窗体 MainWindow 里放一个测试按钮。
<Window x:Class="WpfApp1.MainWindow"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:WpfApp1"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Button Width="100" Height="40" Content="test" Click="Button_Click" /></Grid>
</Window>
再新建一个窗体 Window1,放一个textblock:
<Window x:Class="WpfApp1.Window1"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:WpfApp1"mc:Ignorable="d"Title="Window1" Height="450" Width="800"><Grid><TextBlock x:Name="tb" Width="100" Height="40" /></Grid>
</Window>
后台代码:
public partial class MainWindow : Window
{private Window1 _win1;private Thread _thread;public MainWindow(){InitializeComponent();Test();}public void Test(){_thread = new Thread(() =>{_win1 = new Window1();_win1.ShowDialog();});_thread.SetApartmentState(ApartmentState.STA);//设置为 STA 才能操作UI_thread.Start();}
}
按钮测试代码:
private void Button_Click(object sender, RoutedEventArgs e)
{Dispatcher.Invoke(()=> {_win1.tb.Text = "from thread";});
}
这个时候,上面的代码是没法执行的,因为 _win1 根本不在主UI线程,执行会crash.
改为下面就正确了:
private void Button_Click(object sender, RoutedEventArgs e)
{Dispatcher dispatcher = System.Windows.Threading.Dispatcher.FromThread(_thread);dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>{_win1.tb.Text = "from thread";}));
}
附:如果使用的是 Task ,是没法直接设置 ApartmentState.STA 的,需要包装一下,如:
private async Task<bool> Test()
{return await StartSTATask<bool>(() => {_win1 = new Window1();_win1.ShowDialog();return true;});
}private Task<T> StartSTATask<T>(Func<T> func)
{var tcs = new TaskCompletionSource<T>();_thread = new Thread(() =>{try{tcs.SetResult(func());}catch (Exception e){tcs.SetException(e);}});_thread.SetApartmentState(ApartmentState.STA);_thread.Start();return tcs.Task;
}
这篇关于WPF Dispatcher.FromThread的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!