代码可以工作,但是当它工作时它会滞后。它适用于foreach并循环它

时间:2014-07-21 23:33:55

标签: c# arraylist foreach

当代码工作如此滞后时,它会非常好,以便在工作时不会出现延迟。

代码的工作原理:

它会在计算机上搜索一个文件,然后当它找到它来更改文件时,但如果文件正在运行,行将循环直到它设法完成它的工作。

主要课程

public Form1(string[] Args)
    {
        InitializeComponent();
        backgroundWorker1.RunWorkerAsync();
    }    

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Thread.Sleep(1000); // One second.Thread.Sleep(1000); // One second.
        MessageBox.Show("Testing");
        Fille mc = new Fille();
        mc.Search();
    }

Fille clss

private static ArrayList list2 = new ArrayList();
private static ArrayList listRemove = new ArrayList();


public void Search()
    {
        try
        {
            foreach (string file in Directory.EnumerateFiles(@"C:\Users\user\Downloads\MCFILE\trrtrt\", "*.exe", SearchOption.AllDirectories))
            {
                // Display file path.
                if (SHA1Hash.GetSHA1Hash(file) == "1233456") // fake SHA1Hash
                {
                    try
                    {
                        COPYWithReplace(@"C:\Users\user\Downloads\MCFILE\Fake2\Test.exe", file);
                    }
                    catch (IOException)
                    {
                        // log errors
                        if (list2.Count == 0)
                        {
                            list2.Add(file);
                            Thread thread = new Thread(new ThreadStart(Test2));
                            thread.Start();
                        }
                        else
                        {
                            Thread thread = new Thread(new ThreadStart(Test2));
                            thread.Abort();
                            list2.Add(file);
                            thread.Join();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // log errors
        }
    }

private void Test2()
    {
        if (list2.Count == 0)
        {
        }
        else
        {

            foreach (string _item in list2)
            {
                try
                {
                    //Run
                    COPYWithReplace(@"C:\Users\user\Downloads\MCFILE\Fake2\Test.exe", _item);
                    listRemove.Add(_item);
                }
                catch (IOException)
                {
                    //error
                }
            }
            foreach (var Remove in listRemove)
            {
                list2.Remove(Remove);
            }
            listRemove.Clear();
            if (list2.Count == 0)
            {
            }
            else
            {
                Thread thread = new Thread(new ThreadStart(Test2));
                thread.Start();
            }

        }
    }

我创建了一个新线程,因为我发现了问题。但现在只是它滞后了。

1 个答案:

答案 0 :(得分:2)

我怀疑它的原因是"落后"是因为您的系统处于一个非常复杂但相当处理器密集型和I / O密集型循环中。如果文件在第一次测试时失败,则代码会启动一个再次尝试它的线程。如果失败,那么你开始另一个线程再次尝试,泡沫,冲洗,重复。

这绝对杀死表现。你基本上是这样做的:

while (forever)
{
    if I can overwrite the file
    {
        break;
    }
}

除非您有多个您尝试编写的文件,否则您将为每个文件执行该循环。同时。而你不只是使用循环。相反,你可以像没有人一样开始和停止线程。

是的,这会让你的电脑变慢。

更合理的方法是使用线程进行第一次检查,使用计时器来限制进行其他检查的频率。通信是一个简单的队列,因为一次只有一个线程可以访问它。

以下是我的建议:

private static Queue<string> filesToCheck = new Queue<string>();
private System.Timers.Timer copyTimer;

public void Search()
{
    try
    {
        foreach (string file in Directory.EnumerateFiles(@"C:\Users\user\Downloads\MCFILE\trrtrt\", "*.exe", SearchOption.AllDirectories))
        {
            // Display file path.
            if (SHA1Hash.GetSHA1Hash(file) == "1233456") // fake SHA1Hash
            {
                if (!TryToCopy(file))  // See function below
                {
                    filesToCheck.Enqueue(file);
                }
            }
        }
        // Checked all the files once.
        // If there are any in the queue, start the timer.
        if (filesToCheck.Count > 0)
        {
            copyTimer = new System.Timers.Timer(CopyTimerProc, null, 1000, Timeout.Infinite);
        }

    }
    catch (Exception)
    {
        // do your error handling
    }
}

private void CopyTimerProc(object state)
{
    string filename = filesToCheck.Dequeue();
    if (TryToCopy(filename))
    {
        // success. If the queue is empty, kill the timer.
        if (filesToCheck.Count == 0)
        {
            copyTimer.Dispose();
        }
    }
    else
    {
        // File still locked.
        // Put it back on the queue and reset the timer.
        filesToCheck.Enqueue(filename);
        copyTimer.Change(1000, 0);
    }
}

private bool TryToCopy(string filename)
{
    try
    {
        COPYWithReplace(@"C:\Users\user\Downloads\MCFILE\Fake2\Test.exe", filename);
        return true;
    }
    catch (IOException)
    {
        // log error
        return false;
    }
}

计时器是一次性的,在每次滴答后重置。我这样做的原因是为了防止在前一个滴答仍在处理时出现另一个滴答。毕竟,复制文件需要时间。

没有理由用一堆线程来做这件事。无论如何,文件系统一次只能做一件事,当你等待一个文件可用时,它不会像额外的一两秒那样会伤害任何东西。