用于更新数据网格的线程
我有一个窗口,里面有 Telerik gridview,我每 1 分钟更新一次这个 gridview。我有一个刷新方法,每 1 分钟调用一次。
我无法使用BackgroundWorker,因为我的CollectionViewSource位于UI线程中,而backgroundworker无法使用它。我的问题是如何从另一个线程调用此刷新方法?
我在某处看到这个示例代码:
Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Refresh()));
这是我在 Refresh_Executed 中使用上述代码的真实方法吗? 请帮我。
这是我的刷新方法:
public ObservableCollection<RequestView> AllRequestsData { get; set; }
private void Refresh()
{
using (ArchiveEntities db = new ArchiveEntities())
{
var data = db.RequestSyncs.Where(x => x.UserId == null);
if (data.Any())
{
string IdList = String.Join(",", data.Where(x => x.IsNew).Select(x => x.RequestId));
if (!String.IsNullOrWhiteSpace(IdList))
{
foreach (var item in db.RequestViews.Where("it.id in {" + IdList + "}"))
{
this.AllRequestsData.Add(item);
}
}
foreach (var item in data.Where(x => x.IsDeleted))
{
RequestView rv = this.AllRequestsData.Where(x => x.Id == item.RequestId).SingleOrDefault();
if (rv != null)
{
this.AllRequestsData.Remove(rv);
}
}
foreach (var item in data)
{
db.RequestSyncs.DeleteObject(item);
}
db.SaveChanges();
}
}
}
谢谢
I have a window with a telerik gridview in it and i update this gridview every 1 minute. i have a refresh method and every 1 minute i call it.
i cant use BackgroundWorker because my CollectionViewSource is in the UI thread and backgroundworker cant use it. my question is how can i call this refresh method from another thread?
somewhere i see this sample code:
Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Refresh()));
is this a true way that i use the above code in Refresh_Executed?
please help me.
this is my Refresh method:
public ObservableCollection<RequestView> AllRequestsData { get; set; }
private void Refresh()
{
using (ArchiveEntities db = new ArchiveEntities())
{
var data = db.RequestSyncs.Where(x => x.UserId == null);
if (data.Any())
{
string IdList = String.Join(",", data.Where(x => x.IsNew).Select(x => x.RequestId));
if (!String.IsNullOrWhiteSpace(IdList))
{
foreach (var item in db.RequestViews.Where("it.id in {" + IdList + "}"))
{
this.AllRequestsData.Add(item);
}
}
foreach (var item in data.Where(x => x.IsDeleted))
{
RequestView rv = this.AllRequestsData.Where(x => x.Id == item.RequestId).SingleOrDefault();
if (rv != null)
{
this.AllRequestsData.Remove(rv);
}
}
foreach (var item in data)
{
db.RequestSyncs.DeleteObject(item);
}
db.SaveChanges();
}
}
}
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,使用
Dispatcher
是完成大多数浅色背景工作的正确方法。但请注意,在 Dispatcher 上完成的繁重后台工作可能会锁定 UI,因为它仍在主 UI 线程上运行。如果您有大量处理,我建议使用
BackgroundWorker
,任务并行库,或某种其他形式的多线程(我更喜欢await
/async
,但这仅在 C#5.0 或 AsyncCTP 刷新)另外,我建议刷新
DataGrid
绑定到的集合,而不是刷新DataGrid
本身。我认为刷新 DataGrid 将重新绘制所有 UI 元素,而刷新ItemsSource
将在可能的情况下简单地重新使用现有的 UI 元素。Yes, using the
Dispatcher
is the correct way to do most light background work.Be warned however that heavy background work done on the
Dispatcher
can lock up the UI, since it is still running on the main UI thread. If you have a large amount of processing I would recommend using aBackgroundWorker
, Task Parallel Library, or some other form of multi-threading (I preferawait
/async
, however that's only available in C#5.0 or the AsyncCTP Refresh)Also, I would recommend refreshing the Collection the
DataGrid
is bound to instead of theDataGrid
itself. I think refreshing the DataGrid will re-draw all the UI elements, while refreshing theItemsSource
will simply re-use the existing UI elements if possible.可能是共同点,这是真实的方式,但这取决于
Refresh
方法的内容,你能提供它的内容吗?编辑
通常我使用异步标题在视图模型中加载数据,并且实际上不需要更新 RadGridView。但是,例如,当我需要折叠所有组等时,我使用 radGridView.Dispatcher.BeginInvoke(...)。
更新
无需更新
RadGridView
。您正在更新它的ItemsSource
属性。在这种情况下,我不建议使用Dispatcher
,我会使用 任务并行库从数据库接收纯数据并更新ItemsSource
并与当前UI线程同步:注意,您应该升级此方法来实现您的需求(您可以将您在第一个任务中使用数据库方法,并且可能会从两个集合中返回元组),这只是一个想法。
May be in common it's true way, but it depends on content of the
Refresh
method, could you provide the content of it?EDIT
Usually I load data in view model using async theads and don't really need to update RadGridView. But when, for instance, I need to collapse all groups e.t.c I use radGridView.Dispatcher.BeginInvoke(...).
UPDATE
There is no need to update
RadGridView
. You are updating it'sItemsSource
property. I would not reccomend to useDispatcher
in such situation and I would use Task Parallel Library to recieve plain data from database and updateItemsSource
with the synchronization with the current UI thread:Note, that you should upgrade this method to implement your needs (you could put you database methods in first task and may be return
Tuple
from two colelctions) and this is just idea.自 .NET 4 发布以来,使用 TPL 是线程处理的最佳方法...
Using the TPL is the best way to go when it comes to threading since .NET 4 was released...