如何在Action中传递字符串参数?

时间:2014-08-29 08:12:41

标签: c# .net action producer-consumer

我有这个班级:

public class PCQueue : IDisposable
{
  public delegate void OnFileAddDelegate(string file);
  public event OnFileAddDelegate OnFileAddEventHandler;
  BlockingCollection<Action> _taskQ = new BlockingCollection<Action>(); 
  public PCQueue (int workerCount)
  {
    // Create and start a separate Task for each consumer:
    for (int i = 0; i < workerCount; i++)
      Task.Factory.StartNew (Consume);
  }

  public void Dispose() { _taskQ.CompleteAdding(); }

  public void EnqueueTask (Action action) { _taskQ.Add (action); }

  void Consume()
  {
    // This sequence that we’re enumerating will block when no elements
    // are available and will end when CompleteAdding is called. 
    foreach (Action action in _taskQ.GetConsumingEnumerable())
      action();     // Perform task.
  }
}

我有string[]我希望添加到Queue中,之后我希望我的Consume()获取此文件以便处理。

string[] files;

PCQueue pq = new PCQueue(1);
foreach (string item in files)
    pq.EnqueueTask(item);

我有这个错误:无法转换为&#39; string&#39;到&#39; System.Action&#39;

我从Queue发出文件后,我会检查此文件:

Checker checker = new Checker ();
string result = Checker.Check(my file from the Queue);
if (result != null && OnFileAddEventHandler != null)
    OnFileAddEventHandler(result);

如果这个文件没问题我将事件发送到我的表单

1 个答案:

答案 0 :(得分:0)

如果我理解你的意图,你不需要为你的Action添加一个参数,你需要的是改变你调用EnqueueTask方法的方式。 例如,如果要将ProcessFile(string filename)方法的执行排入队列,则必须将代码更改为:

foreach (string item in files)
{
    string filename = item;
    pq.EnqueueTask(() => ProcessFile(filename));
}

制作filename变量的原因是为了避免关闭foreach循环变量,根据您使用的C#版本,这可能是有害的,如this精彩文章中进一步说明的那样

UPD。:你似乎误解了PCQueue班级的作用。它的工作不是为你存储文件名,而是存储你想要做的Action,然后通过Consume()方法执行所有文件名。这些行为根本不必与文件相关,它们可以是任何东西。

但我真的不需要PCQueue来完成你的任务。您使用它的方式,只是循环遍历您的文件效率不高:

Checker checker = new Checker ();
foreach (string item in files) 
{
    string result = Checker.Check(my file from the Queue);
    if (result != null && OnFileAddEventHandler != null) 
    {
        OnFileAddEventHandler(result);
    }
}