使用多线程c#创建多个文件

Posted

技术标签:

【中文标题】使用多线程c#创建多个文件【英文标题】:create multiple files using multiple threads c# 【发布时间】:2020-01-19 18:45:42 【问题描述】:

我正在创建控制台应用程序来模拟服务器。我使用多个线程一起创建多个病毒文件,以查看是否所有文件都被隔离,如果是,隔离需要多长时间。多线程应用程序的问题是一个线程开始写入另一个线程,所以我得到异常 - 该进程无法访问文件 X,因为该文件正在被另一个进程使用。这就是所有文件都不会被隔离的原因。我使用框架 4.5.2 我已经使用线程和任务创建了应用程序。我没有得到想要的结果。编写此应用程序的最佳实践是什么?感谢您提前帮助我。

使用线程:

class Program

    static string folderPath;
    static readonly string fileContent = @"X5O!P%@AP[4\PZX54(P^)7CC)7$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*";

    static void Main(string[] args)
    
        folderPath = "F:\VirusScan";

        int counter = 1000;
        for (int i = 0; i < counter; i++)
        
            var thread = new Thread(() => GenerateVirusFile(i));
            thread.Start();
        

        Console.ReadKey();
    

    static void GenerateVirusFile(int i)
    
        string filePath = $@"folderPath\TestForVirusScan_i_DateTime.Now.ToString("yyyyMMddHHmmssffff").txt";

        try
        
            using (StreamWriter writer = new StreamWriter(filePath))
            
                writer.WriteLine(fileContent);
            

            var timer = Stopwatch.StartNew();
            while (true)
            
                if (!File.Exists(filePath))
                
                    Console.WriteLine($"i: File was removed in timer.ElapsedMillisecondsms");
                    break;
                
                else
                
                    Thread.Sleep(1);
                
            
        
        catch (Exception ex)
        
            Console.WriteLine($"i: Exception ex.GetType().Name occurred: ex.Message");
        
    

使用任务:

class Program

    static string folderPath;
    static readonly string fileContent = @"X5O!P%@AP[4\PZX54(P^)7CC)7$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*";

    static void Main(string[] args)
    
        folderPath = "F:\VirusScan";

        int counter = 1000;
        List<Task> tasks = new List<Task>();

        for (int i = 1; i <= counter; i++)
        
            Task newTask = new Task((x) => GenerateVirusFile(x), i);                
            tasks.Add(newTask);
        

        foreach (var task in tasks)
        
            task.Start();
        

        Task.WaitAll(tasks.ToArray()); 

        Console.ReadKey();
    

    public static void GenerateVirusFile(object i)
    
        string filePath = $@"folderPath\TestForVirusScan_i_DateTime.Now.ToString("yyyyMMddHHmmssffff").txt";

        try
        
            using (StreamWriter writer = new StreamWriter(filePath))
            
                writer.WriteLine(fileContent);
            

            var timer = Stopwatch.StartNew();
            while (true)
            
                if (!File.Exists(filePath))
                
                    Console.WriteLine($"i: File was removed in timer.ElapsedMillisecondsms");
                    break;
                
                else
                
                    Thread.Sleep(1);
                
            
        
        catch (Exception ex)
        
            Console.WriteLine($"i: Exception ex.GetType().Name occurred: ex.Message");
        
    

【问题讨论】:

您收到该错误的原因是您试图从 多个线程 中读取 同一个文件。将代码更改为读取一次,这不需要在每个线程中完成并且不能同时完成,一旦将内容的副本传递给多个线程进行写入......确保它们的名称是唯一的(如果相同)目录。 这就像我见过的最奇怪的测试一样,如果知道它是 1 秒还是 1 分钟,你会得到什么,这取决于你的防病毒软件是否开启了访问*扫描,如果不是,您将不得不安排一次扫描,因此大多数 gd 都会进行一次访问扫描。 不过,它不是同一个文件,除非我遗漏了什么。变量i 被传递给每个线程/任务并合并到文件名中。 请注意,尝试启动 1000 个任务不会使所有 1000 个写入同时发生。计划的任务(或线程)数量是有限制的。 您可以通过使用文件监视器来监视删除而不是轮询 File.Exists 在一个紧密的循环中为一千个文件存在,从而显着减少 IO 请求(并提高测试的并发性)。 【参考方案1】:

问题出在以下代码中:

for (int i = 0; i < counter; i++)

    var thread = new Thread(() => GenerateVirusFile(i));
    thread.Start();

闭包() =&gt; GenerateVirusFile(i) 正在引用变化的变量 改写如下:

Parallel.For(0, counter, GenerateVirusFile);

【讨论】:

【参考方案2】:

你有没有在你的循环中尝试过这样的事情:

    int x = i;
    var thread = new Thread(() => GenerateVirusFile(x));

这可以防止相同的i 用于更多线程/文件名。

【讨论】:

不确定这增加了什么价值,仍然没有意义。 这个解决方案没有帮助。

以上是关于使用多线程c#创建多个文件的主要内容,如果未能解决你的问题,请参考以下文章

C#使用线程窗口调试多线程程序

c#多线程,怎么等待别的线程都结束?谢谢!!

C#使用线程窗口调试多线程程序

C#多线程之旅

C#怎么开辟多线程,要是多了是不是会出错,出错了怎么办?

C#多线程之旅