【问题标题】:create multiple files using multiple threads c#使用多线程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.ElapsedMilliseconds}ms");
                    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.ElapsedMilliseconds}ms");
                    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 请求(并提高测试的并发性)。

标签: c# asp.net multithreading task


【解决方案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 用于更多线程/文件名。

    【讨论】:

    • 不确定这增加了什么价值,仍然没有意义。
    • 这个解决方案没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    相关资源
    最近更新 更多