我想從小型「塊」或頁面中的數據庫中讀取大量的行並向用戶報告進度;即,如果我在加載每個塊時加載了100個「塊」報告進度。什麼是從TPL任務報告WPF視圖進度的適當方式?
我在C#4.0中使用TPL從數據庫中讀取這些塊,然後將完整結果集交給可以使用它的另一個任務。我覺得TPL可以讓我更好地控制任務取消和交付,比BackgroundWorker等更好,但似乎沒有內置的方式來報告任務的進度。
下面是我已經實現的向WPF進度條報告進度的解決方案,我想確保這是適當的,並且沒有更好的方法,我應該採取。
我開始通過創建一個簡單的接口,以表示改變進度:
public interface INotifyProgressChanged
{
int Maximum { get; set; }
int Progress { get; set; }
bool IsIndeterminate { get; set; }
}
這些屬性可以被綁定到一個ProgressBar在WPF視圖和接口是由背襯視圖模型,其是負責發起實現數據加載和最終報告的總體進展情況(簡化這個例子):
public class ContactsViewModel : INotifyProgressChanged
{
private IContactRepository repository;
...
private void LoadContacts()
{
Task.Factory.StartNew(() => this.contactRepository.LoadWithProgress(this))
.ContinueWith(o => this.UseResult(o));
}
}
你會發現,我傳遞的視圖模型到庫法作爲INotifyProgressChanged而這正是我はnt,以確保我沒有做錯什麼。
這裏我的思考過程是,爲了報告進度,實際執行工作(這是存儲庫方法)的方法需要訪問INotifyProgressChanged接口,以報告最終更新視圖的進度。下面就讓我們來看看庫法(縮短這個例子):
public class ContactRepository : IContactRepository
{
...
public IEnumberable<Contact> LoadWithProgress(INotifyProgressChanged indicator)
{
var resultSet = new List<Contact>();
var query = ... // This is a LINQ to Entities query
// Set the maximum to the number of "pages" that will be iterated
indicator.Maximum = this.GetNumberOfPages(query.Count(), this.pageSize);
for (int i = 0; i < indicator.Maximum; i++)
{
resultSet.AddRange(query.Skip(i * this.pageSize).Take(this.pageSize));
indicator.Progress += 1; // As each "chunk" is loaded, progress is updated
}
// The complete list is returned after all "chunks" are loaded
return resultSet.AsReadOnly();
}
}
那就是如何庫最終報告通過視圖模型的觀看進度。這是正確的方法嗎?我是否正確使用TPL,違反任何主要規則等?這個解決方案正在發揮作用,正在按照預期報告進展情況,我只是想確保我不會讓自己失敗。
我第二此。您可以將NotificationMessage消息發送到UI以進行更新。 –