任务中的计时器未触发

时间:2014-02-09 09:45:59

标签: c# timer task parallel.foreach

从任务t =新任务(()=> StartScanAsync(path))调用以下代码; 但是计时器Event没有触发,Timer在StartTimer中启动。

private void StartScanAsync(string path)
{
    StartTimer();
    foreach (string fsPath in Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntries(path, "*", SearchOption.AllDirectories, true))
    {
        Alphaleonis.Win32.Filesystem.FileInfo finfo = new Alphaleonis.Win32.Filesystem.FileInfo(fsPath);
        fileClass.AddFile(finfo);
        //  UpdateStatus(fsPath);
        UpdateTotalFilesScanned();
        TotalFileSize += finfo.Length;
        UpdateTotalFileSize(TotalFileSize);
        IdentifyFileType.FileType ft = FileType.LoadPathRet(fsPath);
        //  Application.DoEvents();
    }
    UpdateStatus("Done Scanning.");
    StopTimer();
}

我也尝试过Parrallel.ForEach并遇到同样的问题。

以下代码应该启动一个计时器,在一个大集合上运行Parrallel.ForEach然后停止Timer。但是,Timer事件没有被触发......任何想法为什么以及如何解决这个问题?

StartTimer();
Parallel.ForEach(Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntries(path, "*", SearchOption.AllDirectories), fsPath =>
{
    Alphaleonis.Win32.Filesystem.FileInfo finfo = new Alphaleonis.Win32.Filesystem.FileInfo(fsPath);
    fileClass.AddFile(finfo);
    UpdateStatus(fsPath);
    UpdateTotalFilesScanned();
    TotalFileSize += finfo.Length;
    UpdateTotalFileSize(TotalFileSize);
    // IdentifyFileType.FileType ft = FileType.LoadPathRet(fsPath);
    Application.DoEvents();
});
StopTimer();

第一个代码在不在任务中时起作用,第二个代码不在任务中运行但仍然不起作用。

所以澄清:
问题1)为什么计时器(System.Windows.Forms.Timer(我认为))不在任务中触发,并且在围绕Parallel.ForEach时也不会触发?

问题2)如何在Parallel.ForEach任务和任务<>中每秒提高一次Tick(以获取每秒扫描的文件数)任务?

1 个答案:

答案 0 :(得分:4)

.NET提供了不同的计时器。您可以在本文中找到有关Comparing the Timer Classes in the .NET Framework Class Library

的详细列表和说明

问题是您使用的System.Windows.Forms.Timer只能在UI线程上使用。在测试场景中,使用此计时器即使对于这样一个简单的情况也不会起作用:

Task.Factory.StartNew(() =>
{
    var timer = new Timer { Enabled = true, Interval = 1000 };
    timer.Tick += (s, e) => 
        Console.WriteLine("This will never be written to the console!");
});

我假设您使用StartTimerStopTimer方法创建计时器或修改其属性。即使您在UI线程上创建计时器,您实际上也必须在同一UI线程上设置IntervalEnabled

由于您在不同的任务中使用计时器(通过使用Task或Parallel.For),您必须使用不同的计时器,例如System.Threading.Timer

你的第二种情况可能是相同的,但是如果不知道用并行循环调用代码片段的代码就很难说。