繁体   English   中英

即发即忘(但不完全)

[英]Fire and Forget (but not completely)

跟进有关 Fire and Forget 的许多问题中提供的解决方案。 我的场景是我想按顺序运行 Forgotten 事件。

我的解决方案是基于最简单的方法在 c# 4.0 中执行即发即弃的方法

这是我的测试代码。 正如预期的那样,它从不保证它们将被处理的顺序。

    static void Main(string[] args)
    {
        Test(5);
        Console.WriteLine("5 sent");

        Test(2);
        Console.WriteLine("2 sent");

        Test(1);
        Console.WriteLine("1 sent");

        Test(4);
        Console.WriteLine("4 sent");

        Console.WriteLine("all sent");
        Console.ReadLine();

    }

    private static void Test(int messageNumber)
    {
        Action myMethod = () => {
            Task.Delay(messageNumber * 1000);
            Console.WriteLine(messageNumber);
        };
        Blindly.Run(myMethod);
    }

和我的输出

5 sent
2 sent
1 sent
4 sent
all sent
2
1
5
4

想象一下,您正在使用 Fire and Forget 进行日志记录。 所以你不想阻塞调用代码,而是想按照它们发生的顺序写入所有记录的数据。

我会使用 TPL 数据流的ActionBlock (有关介绍,请参阅http://blog.stephencleary.com/2012/09/introduction-to-dataflow-part-2.html

它是一个 NuGet 包,因此请查看它是否符合您的框架版本要求。

static void Main(string[] args)
{
    var a = new ActionBlock<int>(async (messageNumber) => 
    {
        await Task.Delay(messageNumber * 1000);
        Console.WriteLine(messageNumber);
    });

    a.Post(5);
    Console.WriteLine("5 sent");

    a.Post(2);
    Console.WriteLine("2 sent");

    a.Post(1);
    Console.WriteLine("1 sent");

    a.Post(4);
    Console.WriteLine("4 sent");

    Console.WriteLine("all sent");
    Console.ReadLine();
}

它将按照发布到ActionBlock的顺序以即发即忘的方式进行处理。

输出:

5 sent
2 sent
1 sent
4 sent
all sent
5
2
1
4

我会做以下事情:

  • 为所有记录的事件保留时间戳
  • 不要立即将事件写入日志(因为您是异步运行的,所以希望您已经不那么担心了); 而是保留一个记录消息的队列(一个集合,不一定是 FIFO)
  • 每 X 毫秒,如果您将日志消息排队,排序并记录所有早于 Y 毫秒的消息(X 和 Y 将取决于您的要求/设置)
  • 每当应用程序退出时尝试刷新日志(确保您正在执行此操作,即使它是一个例外)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM