【发布时间】:2015-12-15 14:06:53
【问题描述】:
我之前发布过一个类似的问题,但是现在我正在根据我决定采用的特定方法来调整这个问题。
简单地说,我要做的是在用户单击一个页面后显示一条加载消息,当下一页完全加载时(将 27000 家公司加载到 DataGrid 中)然后显示下一页。顺序是这样的;
- 用户点击首页上的按钮
- “请稍候....”显示在同一页面上,而下一页显示 正在加载
- 下一页已完全加载
- 隐藏“请稍候......”
- 显示下一页
向我推荐的是使用async 和wait。然而,这冻结了我的 UI 并且无法正常工作 (Additional information: The calling thread cannot access this object because a different thread owns it.)。然后我开始考虑使用多个线程,希望能解决我的问题。这是我迄今为止所尝试的;
用户点击了进入下一页的按钮
public CompanyManagement()
{
InitializeComponent();
Thread thread = Thread.CurrentThread;
this.DataContext = new
{
ThreadId = thread.ManagedThreadId
};
}
页面的 Loaded 事件被调用;
private void PageLoaded(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
var wait = new PleaseWait("My title", "My Message", () => FillDataGrid());
wait.ShowDialog();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
FillDataGrid() 是一直占用时间的方法(通过 OleDB 检索公司),看起来像这样;
private void FillDataGrid()
{
var _cDS = new CompanyDataService();
var Companies = new ObservableCollection<CompanyModel>();
Companies = _cDS.HandleCompanySelect();
CompanyICollectionView = CollectionViewSource.GetDefaultView(Companies);
//CompanyICollectionView.SortDescriptions.Add(new SortDescription("CompanyName", ListSortDirection.Ascending));
DataContext = this;
cancelButton.Visibility = Visibility.Hidden;
if (compNameRad.IsChecked == false &&
compTownRad.IsChecked == false &&
compPcodeRad.IsChecked == false)
{
searchBox.IsEnabled = false;
}
dataGrid.SelectedIndex = 0;
SetDefaultFilter();
}
这几乎在加载下一页时起作用,显示“请稍候...”但是我得到错误:调用线程无法访问此对象,因为不同的线程拥有它。我是否错误地使用了线程功能?
编辑:我也应该显示PleaseWait!
public partial class PleaseWait : Window
{
readonly Action _action;
public PleaseWait(string title, string message, Action action)
{
_action = action;
InitializeComponent();
this.Title = title;
this.label.Content = message;
}
private async void loaded(object sender, RoutedEventArgs e)
{
await Task.Run(() => _action());
this.Close();
}
}
编辑:对于 StepUp;
private void PageLoaded(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
var wait = new PleaseWait("My title", "My Message", () => FillDataGrid());
wait.ShowDialog();
Dispatcher.Run();
}));
}
【问题讨论】:
-
如果您在以下回复中看到答案,请将其标记为答案。请阅读这篇文章:meta.stackexchange.com/questions/5234/…
标签: c# wpf multithreading