2011-06-20 28 views
6

Herkes, uzun süreçlerin durumunu/ilerlemesini raporlamak/izlemek için iyi bir Tasarım Kalıbı önerebilir. Resim bağlamda dayanarakUzun süreçlerin raporlanması/izlenmesi için tasarım deseni

public class DataContext : IDataContext 
{ 
    pulbic Dictionary<string, objects> Properties { get; private set; } 

    // Additional properties removed for simplicity... 
} 

, bir görev (değil TPL-Görev) nesne oluşturulduğunda, farklı alt görevler ile: Temel olarak, bir "veri içeriği" nesne alan bir kod temeli vardır. Yürütme sırasında DataContext nesnesi, farklı alt görevlere aktarılır ve bunları geri alabilir veya güncelleyebilir. Örneğin, ana görevin bir "Dosyaları kopyala" görevi olduğunu varsayalım. DataContext, SourceFolder ve TargetFolder ve belki bir FilterFiles özelliği (ör. * .docx) gibi özelliklere sahip olacaktır. Ana görevimiz bir CopyFilesTasks olacak ve bir "pipeline" altkümesi olacak - Tarama Klasörleri, Dosyaları Tara, Dosyaları Filtrele, Dosyaları Kopyala, vb ...

Aradığım en iyi yoldur Görev/alt görevlerin ilerlemesini arayan/yürütücüye bildirmelerine izin vermek. Yukarıdaki örneğimizde, devam eden değişiklikler sadece "Kopyalanan dosya ABC.docx ..." ya da "Klasör XYZ ... tarama" gibi biraz daha "karmaşık" bir şey olabilir.

Düşündüm aşağıdaki seçenekler: INotifyPropertyChanged

  1. : DataContext

    bir "İlerleme" özelliği eklemek

    kamu dize İlerleme {get; {_progress = değer; ("Progress") RaisePropertyChanged;

    ve DataContext nesnesinin oluşturulduğu kodu PropertyChanged olayına sahip ol. çeşitli görevler/alt görevlere bir Ilog örneğini kullanın ve ana görev cellat vardır: Ancak, bu

  2. Ilog (tercih ne olursa olsun günlük çerçevesini kullanarak) ... bir çok-basit bir yaklaşım gibi görünüyor günlüğe kaydetme çerçevesine kendi dinleyicisini ekleyin. Ancak bu, yapılması gereken şeyleri yapmak için kayıt mekanizmasını bükme gibi görünüyordu.

  3. Udi Dahan en DomainEvents: görevin cellat bir "etki" olarak DataContext'i kabul edebilir ve bu nedenle bir "ProgressChanged" etkinliği için "EventHandler" uygulamaya deneyebilirsiniz.

    : Teoride, bu hatta

Benim endişeleri

gibi şeyleri içerir ... Belirli alt görevlere meydana ... Ama bir kez daha, bu kavram zorlayarak gibi hissediyor daha rafine etkinlikler için kullanılabilecek
  • İlerleme, izlenmesi gereken tek "olay" olmayabilir - yukarıdaki örneğimizde, FolderHandled, FileCopied, vb. Gibi daha fazla tanımlanmış şeyler isteyebiliriz, ancak yürütme sırasında tam olayları bilmiyor olabiliriz görevleri (hatırlayın - alt görevler DataContext'e dayalı olarak oluşturulur ve farklı görevlerin yürütülmesine neden olabilir).
  • Görevlerin yürütülmesi bağlamı henüz tanımlanmadı. Şimdilik, sadece görevleri komut satırı uygulamasından çalıştırmayı planlıyorum, bu yüzden hata ayıklama için komut satırına çıktı almak gerekiyor. Daha sonra, bunu bir servise götürdüğümde, bir "dinleyici" nin görevlerin ilerlemesiyle (örneğin) bir veritabanını güncellemesini isteyebilirim.

cevap

0

BackgroundWorkers düşünün. http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx Ayrı bir UI iş parçacığı üzerinde kendi rapor ilerleme olayları vardır.

+0

İhtiyacım olan bu değil - Arka plan iş parçacıklarında kodu çalıştırma konusunda bir sorunum yok ... Daha fazla "tam" bir çözüm arıyorum ve yalnızca bir ilerleme çubuğunun nasıl güncelleneceğini değil UI (BTW, şu anda bir UI bile yok ve muhtemelen asla olmayacak) – SaguiItay

1

Her muhtemel operasyon türü için argümanlar ilan edebilir, dosya işlem için FileOperationEventArgs, veritabanı işlemi vb

public class FileOperationEventArgs : EventArgs 
{ 
    public readonly string SourceFolder; 
    public readonly string TargetFolder; 

    public FileOperationEventArgs(string sourceFolder, string targetFolder) 
    { 
     SourceFolder = sourceFolder; 
     TargetFolder = targetFolder; 
    } 
} 

public class DatabaseUpdateEventArgs : EventArgs 
{ 
    public readonly int RowsUpdated; 

    public DatabaseUpdateEventArgs(int rowsUpdated) 
    { 
     RowsUpdated = rowsUpdated; 
    } 
} 

OperationProgress sınıfı her işlem türü için olayları bildiren için DatabaseUpdateEventArgs söylüyorlar.

public class OperationProgress 
{ 
    public event EventHandler<FileOperationEventArgs> FileCopied; 
    public event EventHandler<DatabaseUpdateEventArgs> DatabaseUpdated; 

    public void OnFileCopied(FileOperationEventArgs a) 
    { 
     if(FileCopied != null) 
      FileCopied(this, a); 
    } 

    public void OnDatabaseUpdated(DatabaseUpdateEventArgs a) 
    { 
     if (DatabaseUpdated != null) 
      DatabaseUpdated(this, a); 
    } 
} 

DataContext oluşturulduğunda OperationProgress belirtilecektir. Alt görev uygulaması ilerlemeyi güncelleyebilir.

public class FileCopySubTask 
{ 
    public void Execute(DataContext context) 
    { 
     context.Progress.OnFileCopied(new FileOperationEventArgs("c:/temp1", "c:/temp2")); 
    } 
} 
+0

Bu, Udi Dahan's DomainEvents'a benzer, ancak daha kısıtlı - olayları yalnızca belirli "bilinen" olaylar için sınırlar - Ben Yeni etkinliklerle yeni görevler için her şeyi derlemek zorundayım ... aynı zamanda birden fazla görev ve birden fazla "dinleyici" varsa, olayların kaydını/kaydını silme ve referansları yönetmem gerekecek ... – SaguiItay

İlgili konular