用于更新数据网格的线程

发布于 2024-12-28 15:51:09 字数 1661 浏览 0 评论 0原文

我有一个窗口,里面有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光的暖冬 2025-01-04 15:51:09

是的,使用 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 a BackgroundWorker, Task Parallel Library, or some other form of multi-threading (I prefer await/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 the DataGrid itself. I think refreshing the DataGrid will re-draw all the UI elements, while refreshing the ItemsSource will simply re-use the existing UI elements if possible.

再可℃爱ぅ一点好了 2025-01-04 15:51:09

可能是共同点,这是真实的方式,但这取决于 Refresh 方法的内容,你能提供它的内容吗?

编辑
通常我使用异步标题在视图模型中加载数据,并且实际上不需要更新 RadGridView。但是,例如,当我需要折叠所有组等时,我使用 radGridView.Dispatcher.BeginInvoke(...)。

更新

无需更新RadGridView。您正在更新它的 ItemsSource 属性。在这种情况下,我不建议使用 Dispatcher,我会使用 任务并行库从数据库接收纯数据并更新ItemsSource并与当前UI线程同步:

Task.Factory.StartNew<IEnumerable<RequestSyncPlain>>(() =>
{
  return result;
}).ContinueWith(_ =>
{
  try
  {
    _.Wait();
  }
  catch (AggregateException ae)
  {
  }

  foreach (var requestSyncPlain in _.Result)
  {
    var requestSync = new RequestSyncViewModel(requestSyncPlain);

    requestSyncObservableCollection.Add(requestSync);
  }
}, TaskScheduler.FromCurrentSynchronizationContext());

注意,您应该升级此方法来实现您的需求(您可以将您在第一个任务中使用数据库方法,并且可能会从两个集合中返回元组),这只是一个想法。

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's ItemsSource property. I would not reccomend to use Dispatcher in such situation and I would use Task Parallel Library to recieve plain data from database and update ItemsSource with the synchronization with the current UI thread:

Task.Factory.StartNew<IEnumerable<RequestSyncPlain>>(() =>
{
  return result;
}).ContinueWith(_ =>
{
  try
  {
    _.Wait();
  }
  catch (AggregateException ae)
  {
  }

  foreach (var requestSyncPlain in _.Result)
  {
    var requestSync = new RequestSyncViewModel(requestSyncPlain);

    requestSyncObservableCollection.Add(requestSync);
  }
}, TaskScheduler.FromCurrentSynchronizationContext());

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.

誰認得朕 2025-01-04 15:51:09

自 .NET 4 发布以来,使用 TPL 是线程处理的最佳方法...

using System.Threading.Tasks;
Task.Factory.StartNew(() => this.Refresh())

Using the TPL is the best way to go when it comes to threading since .NET 4 was released...

using System.Threading.Tasks;
Task.Factory.StartNew(() => this.Refresh())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文