【问题标题】:How to run second process after finish first process完成第一个进程后如何运行第二个进程
【发布时间】:2019-03-08 13:37:55
【问题描述】:

我每 5 秒生成新的文本文件并在其中写入记录。我为这两个过程生成了不同的方法。因此,首先它会创建一个文件并开始在其中写入数据,如果 5 秒后再次创建文件方法访问,则在先前的文件中记录未完全写入。那么我怎样才能使它完成并创建新文件呢?

我正在应用下面的代码来实现:

const string filePath = @"D:\TestSymbolsData.txt";
public static void ReadAndWriteInFile()
{
     Timer timer = new .Timer(new TimerCallback(createtxtFile));
     timer.Change(0L, 5000);

     File.ReadLines(filePath).ToList().Take(1000)
                .AsParallel()
                .Select(JsonConvert.DeserializeObject<List<LiveAMData>>)
                .ForAll(WriteRecordTest);
}

static StreamWriter tempWriter;
static System.Threading.Tasks.Task t1;
public static async void WriteRecordTest(List<LiveAMData> data)
{
     List<LiveAMData> data1 = data.AsParallel().Where(x => symbolList.Contains(x.sym)).ToList();
     foreach (var dt in data1)
     {
          t1 = Task.Run(() =>
          {
              var result = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc).AddTicks(((long)dt.s) * TimeSpan.TicksPerMillisecond);
              DateTime newDT = TimeZoneInfo.ConvertTimeFromUtc(result, targetZone);
              lock(tempWriter)
              {
                  tempWriter.WriteLine(dt.sym + ", " + newDT.ToString("dd/MM/yyyy HH:mm:ss fff tt") + ", " + dt.v);
              }
          });
     }
}

public static void createtxtFile(object state)
{
    if(t1 != null)
    {
        Task.WhenAll(t1);
        sLogFname = $@"D:\LogFiles\{DateTime.Now:yyyyMMdd_HHmmss}.txt";
        tempWriter = new StreamWriter(new FileStream(sLogFname, FileMode.Append, FileAccess.Write));
    }
    else
    {
        sLogFname = $@"D:\LogFiles\{DateTime.Now:yyyyMMdd_HHmmss}.txt";
        tempWriter = new StreamWriter(new FileStream(sLogFname, FileMode.Append, FileAccess.Write));
    }
}

并且在文件中的最后一行变得就像它在进程中间停止并生成新文件。

CORE, 05/02/2019 10:27:00 000 AM, 548
YUM, 05/02/2019 10:27:00 000 AM, 1109
DVY, 05/02/2019 10:27

实际上最后一条记录DVY是一半数据,几乎每个文件都会发生这种情况。

所以我认为这个问题是由于第二个过程(创建文件)而发生的。那么我应该申请什么解决方案来解决这个问题呢?

【问题讨论】:

  • 在创建与文件的新连接之前,您可能必须确保与文件的连接已关闭/处置。
  • @Symon 我已经关闭了该文件的连接,因此它给出了“由于连接关闭而无法写入文件”的错误。文件的连接关闭也存在问题。
  • 您必须重新建立连接才能开始写入该文件。查看using 语句可能会有所帮助。这些将非常无缝地打开和关闭/处理连接

标签: c# multithreading linq task filestream


【解决方案1】:

@Ankit,您删除了包含与您的问题无关的详细信息的代码示例,使得回答您的问题变得更加困难。如果我理解正确,您的问题是关于数据准确性的损失,这很可能是由于线程处理不正确,但您的代码中包含序列化、日志记录和 TimeZone 复杂性。代码 WriteRecordTest(..) 用 async 修饰,但在其中找不到 await。该代码包含未提供的数据类型,为了回答您的问题,我们需要猜测...

从代码本身难以推理的角度出发,我建议对代码进行如下重构:

  1. 生成生产者(发布者)和消费者(订阅者)线程(称为发布-订阅模式):
  2. 生产者:在自己的生产者线程中逐行读取控制器文件@"D:\TestSymbolsData.txt",并将这些行累积到并发缓冲区中,例如ConcurrentQueue&lt;T&gt;,因为这些行是有序的。
  3. 消费者:不同的线程将从缓冲区中检索行,ConcurrentQueue&lt;T&gt;,并将这些行处理为tempWriter。然后每 5 秒tempWriter 将被关闭并创建/打开一个新的。这 5 秒的时间间隔不必是并发的,在处理从缓冲区检索的下一行之前,您可以检查一个计时器,如果计时器小于 5 秒,然后继续消费者的工作。否则,关闭之前的 tempWriter 并创建一个新的并继续 BAU(一切照旧)。
  4. 您需要注意一个空缓冲区并让消费者不要崩溃而是等待。当消费者处理缓冲区中的数据比生产者向缓冲区中生成数据的速度更快时,就会发生这种情况。
  5. 您必须注意缓冲区已满,生产者需要等待而不是崩溃。当生产者生成数据的速度快于消费者从缓冲区处理数据的速度时,就会发生这种情况。
  6. 您需要有一个触发器来发出信号并结束进程。

【讨论】:

    【解决方案2】:

    我认为,使用 tempwriter 对象作为锁定对象是个坏主意……

    但是,更重要的是,您只将 tempwriter 锁定在 WriteRecordTest 中,因此锁定在 createtextfile 中没有用。

    我认为,只要你在自己的一段代码中,甚至在同一个类中,你应该可以使用一个简单的布尔变量来锁定对文件资源的访问

    • 检查布尔值是否为假,如果不是则什么都不做
    • 然后将布尔值设置为 true 并执行您的工作(一方面,写入文件,另一方面刷新文件并重新打开下一个文件)

    有了这个提示,应该可以解决你的问题了……

    [2019-03-11 编辑:]

    起初我认为,为您提供对代码的更正会很容易。但是再看一遍,我看不出你想要达到什么目的。

    【讨论】:

    • @Wolfgand Roth,谢谢你的建议。这是否意味着像在锁定文件上设置 true 或 false 并将该布尔值传递给创建文件?还有我应该用 tempwriter 替换什么?
    • 只需使用private static Boolean bLock;,然后查询此变量并进行相应设置。 (我将编辑我的答案以澄清)。
    • 感谢您的建议。我不断地从文件中接收记录并将其存储在文本文件中。每个文本文件也会在几秒钟内生成。所以所有这些过程都是并行运行的,因此当新文件在 5 秒内生成时,会记录 writer 没有完成它的操作。所以最后一个记录变成了一半。数据丢失在文件中。
    • 我默认将布尔值设置为 false,并在写入文件时设置为 true,再次写入文件后将其设置为 false。我在 WriteRecordTest 中执行的所有这些操作,并将该布尔值检查到 createTextFile 中。就像如果布尔值是假的,那么只创建文本文件,否则它不生成文件。
      但它也给了我们同样的结果。最后的记录仍然是一半。数据丢失在文件中。
    猜你喜欢
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多