在托管代码中创建硬链接

时间:2011-04-29 10:01:33

标签: c# parallel-processing

我正在开发一个创建数十万个硬链接的应用程序(这是应用程序的核心功能)。

我使用dotNET 4.0中现在提供的并行编程功能。这非常有效。请参阅下面的示例snippits。

或者:

Parallel.For(from, until, delegate(int i)
{
    j += 1;
    fileIndex = Convert.ToInt32(Math.Round(j * 0.001) + 1);

    //determine the hardlink files; we have to have an unique name for the hardlink for each individual hardlink
    fileName = fiArray[fileIndex].Name; //Path.GetFileNameWithoutExtension(textBoxFile.Text);
    destinationFileName = Path.Combine(textBoxDestination.Text, string.Concat(fileName, "_", i.ToString(), ".txt"));

    fr.CreateHardLink(destinationFileName, fiArray[fileIndex].FullName);
});

或者:

//loop that does the actual work
for (int i = 0; i < nudThreads.Value; i++)
{
    //determine the work package per task
    from = 0 + until + 1;
    until = (i * (Convert.ToInt32(HardLinks / ThreadNo))) + 1;
    var compute = Task.Factory.StartNew(() =>
    {
        token.ThrowIfCancellationRequested(); //uit boek
        return Work(from, until, false);//todo: counter moet nog worden meegenomen
    }, tokenSource.Token);

    tasks.Add(compute);

    var displayResults = compute.ContinueWith(resultTask => UpdateControls(),
                             CancellationToken.None,
                             TaskContinuationOptions.OnlyOnRanToCompletion,
                             ui);
    CheckedListBoxFiles.Items.Add(DateTime.Now.ToString() + " : Created the hardlinks for: " + displayResults + " files.");
    Application.DoEvents();

    var displayCancelledTasks = compute.ContinueWith(resultTask => UpdateControls(),
                                CancellationToken.None,
                                   TaskContinuationOptions.OnlyOnCanceled, ui);
    CheckedListBoxFiles.Items.Add(DateTime.Now.ToString() + " : Cancelled a task at: " + displayCancelledTasks + " files.");
    Application.DoEvents();
}

我的问题是:CreateHardlink是Kernel32.dll的一部分,因此在UNMANAGED代码中运行。我对并行ctp的了解是并行任务必须在托管代码中运行。 createhardlink是否有托管替代方案?有谁知道如何在托管代码中创建硬链接,是否有人对并行编程和使用非托管代码有任何想法?

3 个答案:

答案 0 :(得分:1)

尝试以并行方式创建硬链接毫无意义。这不是CPU绑定操作,而是I / O绑定。与天真的连续方法相比,我不希望这种方法带来任何性能上的好处。

关于与硬链接创建相关的托管代码和非托管代码的问题很有意思。您必须记住,托管代码的任何I / O访问都会在某些时候调用非托管代码。操作系统不受管理,创建硬链接的唯一方法是通过操作系统。我认为您需要更准确地了解CTP对托管代码的这种限制究竟意味着什么。

答案 1 :(得分:0)

如果您希望能够取消硬链接创建,但又不想进行多线程处理,我要做的是实现生产者/消费者队列 - 一个或多个线程添加“在此路径创建硬链接”工作项队列,一个线程从队列中抓取工作项并为它们创建硬链接。

这为您提供了一些取消的灵活性 - 如果您想要停止所有硬链接创建,您可以中止工作线程,或者如果您只想取消一个项目,您可以在队列中找到它并将其删除。

查看您发布的代码的旁注 - 调用Application.DoEvents()是纯粹的,毫不畏惧的邪恶。每当你打电话给它时,一个小海豹就会自杀身亡。一个更好的方法是在你的用户界面上queue a work item在线程池上,然后使用Dispatcher.Invoke(假设这是WPF - 如果它是Winforms我知道有一个等价但我不知道是什么它是异步更新UI。

答案 2 :(得分:0)

并行使用非托管OS调用不再是从托管代码执行操作的问题。就那么简单。 :)

托管代码只是意味着它在托管上下文中运行(因此CLR可以跟踪事物)。执行方面,无论是托管还是非托管都无关紧要。

如果我没记错,任何kernel32调用都是原子的,这意味着它是线程安全的。