0

私は延期された実行とそのすべてのジャズの大ファンですが、今では少し異なる問題が発生しました。

StartTimeでソートされた現在のマシンで実行されているすべてのプロセスを単純に表示するプロセスモニターの次の最初のナイーブな実装について考えてみます。

public partial class ProcessesByStartTimeForm : Form {

    // ... init stuff

    public static readonly IEnumerable<object> ProcessQuery
        = from p in Process.GetProcesses()
          let startTime = Eval.TryEvalOrDefault<DateTime?>(() => p.StartTime)
          orderby startTime
          select new {
              Process = p.ProcessName,
              StartTime = startTime, // could be null
              Title = p.MainWindowTitle
          };

    private void ProcessesByStartTimeForm_Load(object sender, EventArgs e) {
        this.RefreshDataSource();
    }

    private void refreshToolStripMenuItem_Click(object sender, EventArgs e) {
        this.RefreshDataSource();
    }

    private void RefreshDataSource() {
        this.gridView.DataSource = ProcessQuery.ToList();
    }
}

(注:これEval.TryEvalOrDefault<T>(Func<T> f)は、例外をスローして代わりに返す可能性のあるものを評価するために使用する単なるヘルパーメソッドですdefault(T))。

ここで重要なのは、データソースが評価されるのは1回だけで、正確にはクエリの作成時です。

そして、はい、私は知っています、私はそれを何度も繰り返し作成し続けるメソッド内にこのクエリ定義をラップすることができますが、私のポイントはデータの評価を行うためのある種の巧妙なトリックを取得することであることがわかると思います-クエリが実行されるたびに動的なソース。

4

1 に答える 1

0

HA ...let句とほぼ同じトリックを適用できると思います...Func<IEnumerator<T>>実行時にも評価するラッパーを定義してください!

public partial class ProcessesByStartTimeForm : Form {

    // ... init stuff

    public static readonly IEnumerable<object> ProcessQuery
        = from p in new DeferredEnumerable<Process>(() => Process.GetProcesses())
          let startTime = Eval.TryEvalOrDefault<DateTime?>(() => p.StartTime)
          orderby startTime
          select new {
              Process = p.ProcessName,
              StartTime = startTime, // could be null
              Title = p.MainWindowTitle
          };

    class DeferredEnumerable<T> : IEnumerable<T> {
        readonly Func<IEnumerable<T>> f;

        public DeferredEnumerable(Func<IEnumerable<T>> f) {
            this.f = f;
        }

        public IEnumerator<T> GetEnumerator() {
            return this.f().GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return this.GetEnumerator();
        }
    }
}
于 2012-08-01T19:28:42.817 に答える