Arc*_*Set 2 vb.net wpf taskfactory
如何使用TaskFactory创建新的UI元素?当我尝试时,我收到以下错误:
调用线程必须是STA,因为许多UI组件都需要这个.
示例代码
Dim txtBoxList as new List(Of TextBox)
Sub StartThread()
Dim TS As TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
Task.Factory.StartNew(Sub() CreateControl(), TS)
End Sub
Sub CreateControl()
Dim txtBox As New TextBox
Dispatcher.BeginInvoke(Sub() txtBoxList.Add(txtBox))
End Sub
Run Code Online (Sandbox Code Playgroud)
如果你正在使用WPF,你真的需要留下你可能从古代技术中学到的任何和所有概念,并理解并接受WPF心态.
基本上,你几乎永远需要创建或操纵在WPF程序代码UI元素.相反,WPF有助于大量使用DataBinding.
WPF的线程模型并没有允许你创建或操作在后台线程UI元素的实例,并将它们添加到可视树这是由"主" UI线程创建的.
无论如何,对于这样的事情几乎没有必要,因为创建UI元素在大多数情况下是一个简单的任务,可以(并且必须)由UI线程执行.
而不是担心Visual Tree,你应该专注于在后台线程中加载你的数据,然后作为DataContext传递给UI,以便它可以相应地显示你的数据.
这是一个小例子,它使用一个ItemsControl显示用户列表,这些用户列表在后台线程中异步加载,然后被分派到UI线程进行显示:
<Window x:Class="WpfApplication7.AsyncItemsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="LightGray" BorderBrush="Black" BorderThickness="1" Margin="2">
<StackPanel>
<TextBlock Text="{Binding LastName}" Margin="2"/>
<TextBlock Text="{Binding FirstName}" Margin="2"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
Run Code Online (Sandbox Code Playgroud)
代码背后:
public partial class AsyncItemsControl : Window
{
public AsyncItemsControl()
{
InitializeComponent();
var dispatcher = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew(() => GetUsers())
.ContinueWith(x => DataContext = x.Result,dispatcher);
}
public List<User> GetUsers()
{
// pretend this method calls a Web Service or Database to retrieve the data, and it takes 5 seconds to get a response:
Thread.Sleep(5000);
return new List<User>
{
new User() {FirstName = "Marty", LastName = "McFly"},
new User() {FirstName = "Emmett", LastName = "Brown"},
new User() {FirstName = "Bufford", LastName = "Tannen"}
};
}
}
Run Code Online (Sandbox Code Playgroud)
数据项:
public class User
{
public string LastName { get; set; }
public string FirstName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
结果:

请注意,该示例使用DataBinding,它不会在过程代码中创建或操作UI元素,而是使用User具有简单string属性的简单类进行操作.
另请注意,在5秒"加载"时间内,UI响应,因为实际工作由后台线程执行.
这种方法允许UI和数据之间更大的分离,这允许UI的更大可扩展性和可定制性,而无需改变底层业务/应用程序逻辑.
注意如何ItemsControl创建和呈现显示3个数据项所需的适当的UI元素."每个项目看起来如何"的实际定义是DataTemplate.
我强烈建议您阅读本答案中链接的材料,以便更深入地了解WPF的工作原理.
旁注:如果你的目标是C#5.0,你可以async / await通过删除所有Task基础的东西来利用并使代码更清晰.我在C#4.0上,因此我无法使用该功能.
WPF Rocks.只需复制并粘贴我的代码,File -> New Project -> WPF Application然后自己查看结果.
如果您需要进一步的帮助,请告诉我.
| 归档时间: |
|
| 查看次数: |
697 次 |
| 最近记录: |