在.NET中使用线程处理文件

时间:2015-10-29 07:16:55

标签: c# multithreading semaphore

我有需求我需要并行处理多个文件,所以我选择了这个

的线程
    private static Semaphore _pool = new Semaphore(0, MaxNumberOfProcessors);   
   _pool.WaitOne();
   _pool.Release();

现在我调用 ProcessSingleFile(file,log,f)方法,该方法处理(符合业务)该文件,并使用 StreamWriter 和 StreamReader

现在问题是如果我有15个文件随机处理它们,即有时我在输出目录中找到10个(这个数字是随机的)文件,有时15个(处理全部)。

我正在使用信号量来使用以下函数来获取MaxNumber线程。

{{1}}

任何人都可以让我知道它为什么会随机出现吗?

2 个答案:

答案 0 :(得分:0)

这通常是一个示例,其中通过任务的线程处理更容易使用,然后自己执行。

任务类和任务<TResult&gt; class可以在命名空间System.Threading.Tasks中找到。

最容易创建并开始使用任务。任务开始后,您可以执行其他操作,当您需要任务结果时,请等待它完成。

var myTask = Task.Run( () => MyFunction(myParameters);
// while the task is running do other useful things
// like starting even more tasks
// after a while you need the result
Task.Wait(myTask);
// or if my function returns a TResult:
TResult result = Task.Wait(myTask);

要等到几个任务完成:

Task.WaitAll(severalTasks);

因此,在您的示例中,您的代码就像:

(顺便说一句:在您的示例中,您突然有一个目标文件。我认为这是文件名)

public void ProcessFiles(string inputFilePath)
{
    DirecotryInfo dir = new DirectoryInfo(inputFilePath);
    if (!dir.Exsists)
    {
        ReportProblem(...);
        return;
    }

    var filesToProcess = dir.EnumerateFiles()
        .Where(fileInfo => IsFileNameAcceptable(fileInfo.Name);
    var runningTasks = filesToProcess
        .Select(fileToProcess => Task.Run( () => ProcessSingleFile(file.Name, log, f))
        .ToArray();
    // note: linq uses deferred execution.
    // ToArray is used to make sure the tasks are really started
    // while the tasks are running you can do other things
    // after a while wait for the tasks to finish:
    runningTasks.WaitAll();
}

private bool IsFileNameAcceptable(string fileName)
{
   return !(fileName.ToUpper().Contains("ENCODING") || fileName.Contains("HEADERS"));
   // or did you mean:
   var upperFileName = fileName.ToUpper();
   return !upperFileName.Contains("ENCODING")
       && !upperFileNmae.Contains("HEADERS");
}

最后:有些人喜欢使用Task.Factory.StartNew()启动任务 差异见 Task.Run versus Task.Factory.StartNew

答案 1 :(得分:0)

HD的资源不像您的线程那样可扩展......

您应该使用TPL(Parralele Library)为每个CPU发送作业而不会对整个系统过度充电。在这种情况下,您将拥有一个由CPU限制的最大线程数(通常为2或4),并且您不会对I / O进行附加费。