2012-01-23 37 views
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(); 
      } 
     } 
    } 

感謝

回答

1

可能是在共同它是真實的方式,但它取決於Refresh方法的內容,你能提供它的內容?

編輯 通常情況下,我使用異步方式加載視圖模型中的數據,並且不需要更新RadGridView。但是,例如,當我需要摺疊所有組e.t.c時,我使用radGridView.Dispatcher.BeginInvoke(...)。

UPDATE

沒有必要更新RadGridView。您正在更新它的ItemsSource屬性。我不會reccomend在這樣的情況下,使用Dispatcher,我會用Task Parallel Library從數據庫收到明文數據和更新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()); 

注意,你應該升級此方法來實現你的需求(你可以把你的數據庫方法放在第一個任務中,可能會從兩個colelctions返回Tuple),這只是想法。

+0

我發佈我的刷新方法。 –

0

使用TPL是當它涉及到線程,因爲.NET 4發佈到最好的一段路要走......

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

是,使用Dispatcher是做最亮的背景工作的正確方法。

但是請注意,Dispatcher上執行的重要後臺工作可能會鎖定UI,因爲它仍在主UI線程上運行。如果你有大量的處理,我會建議使用BackgroundWorkerTask Parallel Library,或支持多線程的一些其他形式的(我更喜歡await/async,但是這只是在C#5.0或AsyncCTP Refresh可用)

而且,我會建議刷新收集DataGrid必然而不是DataGrid本身。我認爲刷新DataGrid會重新繪製所有的UI元素,而刷新ItemsSource只會儘可能地重用現有的UI元素。

+0

我發佈我的刷新方法。這是一個非常沉重的工作?感謝您的回答。 –