将值从一个线程传递到另一个线程的最简单方法是使用文件。您将值序列化到文件中,然后反序列化它。因此,您必须使用System.Windows.Markup.XamlWriter/XamlReader 类将UserControl 保存到文件并重新加载。
下面的示例演示了这一点。您可以使用System.IO.Path.GetTempFileName() 方法保存到临时文件。
<Grid>
<Button Content="Create on new thread" HorizontalAlignment="Left" Margin="25,25,0,0" VerticalAlignment="Top" Width="126" Click="Button_Click_1"/>
<Button Content="Deserialize" HorizontalAlignment="Left" Margin="25,63,0,0" VerticalAlignment="Top" Width="126" Click="Button_Click_2"/>
<Label x:Name="Lbl" Margin="25,127,0,0" VerticalAlignment="Top" Height="105" Width="220"/>
</Grid>
代码:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() => { StartSTATask(create); });
}
bool create()
{
Button btn = new Button();
btn.Content = "Press me";
using (var stream = System.IO.File.Create(@"g:\\button.xaml"))
System.Windows.Markup.XamlWriter.Save(btn, stream);
return true;
}
public static Task<bool> StartSTATask(Func<bool> func)
{
var tcs = new TaskCompletionSource<bool>();
var thread = new Thread(() =>
{
try
{
var result = func();
tcs.SetResult(result);
}
catch (Exception e)
{
tcs.SetException(e);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
using (var stream = System.IO.File.OpenRead(@"g:\\button.xaml"))
{
Button btn = System.Windows.Markup.XamlReader.Load(stream) as Button;
Lbl.Content = btn;
}
}