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))。

现在的问题是,数据源只被评估一次,正是在查询形成时。

是的,我知道,我可以将这个查询定义包装在一个不断重新创建它的方法中,但我认为你可以理解我的意思是获得某种巧妙的技巧来评估数据 -源动态,每次执行查询时。

4

1 回答 1

0

哈...我认为我们几乎可以应用与 let 子句中相同的技巧...定义一个Func<IEnumerator<T>>在运行时也评估 a 的包装器!

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 回答