【发布时间】: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