C# 如何一次将超过25000条记录/行读写到文本文件中?

C# 如何一次将超过25000条记录/行读写到文本文件中?,c#,websocket,filestream,C#,Websocket,Filestream,我正在使用web套接字将我的应用程序与股市实时数据提供商连接。所以,当市场活跃,插座打开时,它会在一分钟内给我提供近45000条线路。我正在逐行反序列化它 然后将该行写入文本文件,同时读取文本文件并删除文本文件的第一行。因此,使用套接字处理另一个进程变得很慢。所以,请你能帮助我,我应该如何执行这一过程非常快,像近25000行在一分钟 string filePath = @"D:\Aggregate_Minute_AAPL.txt"; var records = (from line in Fil

我正在使用web套接字将我的应用程序与股市实时数据提供商连接。所以,当市场活跃,插座打开时,它会在一分钟内给我提供近45000条线路。我正在逐行反序列化它 然后将该行写入文本文件,同时读取文本文件并删除文本文件的第一行。因此,使用套接字处理另一个进程变得很慢。所以,请你能帮助我,我应该如何执行这一过程非常快,像近25000行在一分钟

string filePath = @"D:\Aggregate_Minute_AAPL.txt";
var records = (from line in File.ReadLines(filePath).AsParallel()                    
               select line);
    List<string> str = records.ToList();
    str.ForEach(x =>
    {
         string result = x;
         result = result.TrimStart('[').TrimEnd(']');
         var jsonString = Newtonsoft.Json.JsonConvert.DeserializeObject<List<LiveAMData>>(x);
         foreach (var item in jsonString)
         {
             string value = "";
             string dirPath = @"D:\COMB1\MinuteAggregates";
             string[] fileNames = null;
             fileNames = System.IO.Directory.GetFiles(dirPath, item.sym+"_*.txt", System.IO.SearchOption.AllDirectories);
             if(fileNames.Length > 0)
             {
                 string _fileName = fileNames[0];
                 var lineList = System.IO.File.ReadAllLines(_fileName).ToList();
                 lineList.RemoveAt(0);
                 var _item = lineList[lineList.Count - 1];
                 if (!_item.Contains(item.sym))
                 {
                      lineList.RemoveAt(lineList.Count - 1);
                 }
                 System.IO.File.WriteAllLines((_fileName), lineList.ToArray());
                 value = $"{item.sym},{item.s},{item.o},{item.h},{item.c},{item.l},{item.v}{Environment.NewLine}";
                 using (System.IO.StreamWriter sw = System.IO.File.AppendText(_fileName))
                 {
                      sw.Write(value);
                 }
              }
          }
 });
stringfilepath=@“D:\Aggregate\u Minute\u AAPL.txt”;
var records=(来自File.ReadLines(filePath.AsParallel()中的行)
选择行);
List str=records.ToList();
str.ForEach(x=>
{
字符串结果=x;
result=result.TrimStart('[').trimsend(']');
var jsonString=Newtonsoft.Json.JsonConvert.DeserializeObject(x);
foreach(jsonString中的var项)
{
字符串值=”;
字符串dirPath=@“D:\COMB1\MinuteAggregates”;
字符串[]文件名=null;
fileNames=System.IO.Directory.GetFiles(dirPath,item.sym+“*.txt”,System.IO.SearchOption.AllDirectories);
如果(fileNames.Length>0)
{
字符串_fileName=文件名[0];
var lineList=System.IO.File.ReadAllLines(_fileName).ToList();
lineList.RemoveAt(0);
var_item=lineList[lineList.Count-1];
如果(!\u项目包含(项目符号))
{
lineList.RemoveAt(lineList.Count-1);
}
System.IO.File.writeAllines((_文件名),lineList.ToArray();
值=$“{item.sym}、{item.s}、{item.o}、{item.h}、{item.c}、{item.l}、{item.v}{Environment.NewLine}”;
使用(System.IO.StreamWriter sw=System.IO.File.AppendText(_文件名))
{
sw.Write(值);
}
}
}
});

如何使进程快速,若应用程序执行此操作,则需要将近3000到4000个符号。如果没有任何进程,那么它每分钟执行25000行。那么,如何使用所有这些代码来增加行执行时间/进程呢?

首先,您需要清理代码以获得更多的可见性,我进行了快速重构,这就是我得到的

const string FilePath = @"D:\Aggregate_Minute_AAPL.txt";

class SomeClass
{
    public string Sym { get; set; }
    public string Other { get; set; }
}

private void Something() {
    File
        .ReadLines(FilePath)
        .AsParallel()
        .Select(x => x.TrimStart('[').TrimEnd(']'))
        .Select(JsonConvert.DeserializeObject<List<SomeClass>>)
        .ForAll(WriteRecord);
}

private const string DirPath = @"D:\COMB1\MinuteAggregates";
private const string Separator = @",";

private void WriteRecord(List<SomeClass> data)
{
    foreach (var item in data)
    {
        var fileNames = Directory
            .GetFiles(DirPath, item.Sym+"_*.txt", SearchOption.AllDirectories);
        foreach (var fileName in fileNames)
        {
            var fileLines = File.ReadAllLines(fileName)
                .Skip(1).ToList();
            var lastLine = fileLines.Last();
            if (!lastLine.Contains(item.Sym))
            {
                fileLines.RemoveAt(fileLines.Count - 1);
            }
            fileLines.Add(
                new StringBuilder()
                    .Append(item.Sym)
                    .Append(Separator)
                    .Append(item.Other)
                    .Append(Environment.NewLine)
                    .ToString()
            );
            File.WriteAllLines(fileName, fileLines);
        }
    }
}
我试图保持简单,但有一些注释: -如果您可以创建自己的方法,那么通过改变睡眠时间,这可能是一种改进,但是您需要很好地了解异步是如何工作的 -如果冲突经常发生,那么您应该尝试另一种方法,比如使用

第二次编辑

在真实场景中,我连接到websocket并收到70000到 每分钟1个lac记录,然后我将这些记录分为两部分 记录实时流式数据并存储在自己的文件中。及 当我将我们的概念应用于11000个文件时,速度会变慢

这是一个很难解决的问题,据我所知,你说的是每秒1166条记录,在这种规模下,小细节可能成为大瓶颈

在那个阶段,我认为最好考虑其他解决方案,可能是磁盘的i/O太多,可能是线程太多,或者网络太少

你应该从分析应用程序开始,检查应用程序在该领域花费更多时间的地方,使用了多少资源?你有多少资源?内存、处理器、垃圾收集器、网络的性能如何?你有SSD吗

你需要清楚地了解是什么让你慢下来,这样你就可以直接攻击它,这将取决于很多事情,这将很难帮助你:(


有很多方法可以解决这个问题(将费用分摊到多个服务器上,使用redis之类的工具快速保存数据,使用一些事件存储以便使用事件…

将请求拆分为多个并行请求,每个请求返回的项目较少。可能会将26个请求拆分为一个以字母表中不同字母开头的股票名称请求。您好@jdweng,请点击y你可以向我详细解释一下你的建议。这是串行操作和并行操作之间的区别。如果完成一项工作需要5天。一个人需要5天,而5个人只需要一天。你首先必须确定是什么让应用程序变慢了。是以太网速度还是应用程序速度。以太网是非常快,所以我不同意你的假设,即这是文本的阅读。序列化是一个缓慢的过程,可能会导致问题。为了加快速度,你可以让读者将库存报告生成到不同的并行任务中。使用不同的反序列化方法,你可能会获得更好的速度。您好,@rekiem87,非常感谢您的最佳答复。我我们已经应用了它并运行得很好。但是我们在这方面遇到了一些问题。我们的目录中有将近10000个文件。因此,当进程运行时,它传递了一个错误,
进程无法访问该文件,因为它正被另一个进程使用。
。因此,当我调试它时,请根据我的想法查找它,因为一次有多个线程。那么有什么方法来处理这个问题吗?编辑了我的答案,我希望它能帮助我尝试1100个文件,它工作得更好,没有任何障碍。但是当我为10000个文件使用这个概念时,它需要时间。那么,对于处理10000个文件的数据,我们可以更新/修改我们的这个代码吗?这样它就可以执行很快。在真实场景中,我连接到websocket,每分钟接收70000到1条lac记录,之后我将这些记录与实时流数据分开,并存储在它自己的文件中。当我将我们的概念应用于11000个文件时,速度会变慢。
private const int SleepMillis = 5;
private const int MaxRetries = 3;

public void WriteFile(string fileName, string[] fileLines, int retries = 0)
{
    try
    {
        File.WriteAllLines(fileName, fileLines);
    }
    catch(Exception e) //Catch the special type if you can
    {
        if (retries >= MaxRetries)
        {
            Console.WriteLine("Too many tries with no success");
            throw; // rethrow exception
        }
        Thread.Sleep(SleepMillis);
        WriteFile(fileName, fileLines, ++retries); // try again
    }
}