c# - 动态 C# 对象的设计模式

标签 c# design-patterns

我有一个在 while 循环中处理对象的队列。它们是在某处异步添加的……像这样:

myqueue.pushback(String value);

它们是这样处理的:

while(true)
{
    String path =  queue.pop();
    if(process(path))
    {
        Console.WriteLine("Good!");
    }
    else
    {
        queue.pushback(path);
    }
}

现在,问题是我想修改它以支持类似 TTL(生存时间)标志,因此文件路径将被添加超过 n 次。

我如何做到这一点,同时保留 bool process(String path) 函数签名?我不想修改它。

我想持有一个 map ,或者一个列表,用于计算过程函数为路径返回 false 的次数,并在第 n 次返回 false 时从列表中删除该路径。我想知道如何更动态地完成此操作,最好是我希望 TTL 在每个新添加的过程中自动递减。我希望我不是在说垃圾话。 也许使用这样的东西

class JobData
{
   public string path;
   public short ttl;

   public  static implicit operator String(JobData jobData) {jobData.ttl--; return jobData.path;}
}

最佳答案

我喜欢 JobData 类的想法,但已经有一个答案证明了这一点,而且您正在使用文件路径这一事实为您提供了另一个可能的优势。某些字符在文件路径中无效,因此您可以选择一个字符用作分隔符。这里的优点是队列类型仍然是一个字符串,因此您不必修改任何现有的异步代码。您可以在此处查看保留路径字符列表:

http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words

出于我们的目的,我将使用百分号 (%) 字符。然后你可以修改你的代码如下,其他什么都不需要改变:

const int startingTTL = 100;
const string delimiter = "%";

while(true)
{
    String[] path =  queue.pop().Split(delimiter.ToCharArray());
    int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;

    if(process(path[0]))
    {
        Console.WriteLine("Good!");
    }
    else if (ttl > 0)
    {
        queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));             
    }
    else
    {
        Console.WriteLine("TTL expired for path: {0}" path[0]);
    }
}

同样,从纯架构的角度来看,具有两个属性的类是更好的设计……但从实用的角度来看,YAGNI :此选项意味着您可以避免返回并更改插入队列的其他异步代码。该代码仍然只需要知道字符串,并且可以使用未修改的字符串。

还有一件事。我想指出这是一个相当紧凑的循环,很容易与 cpu 核心一起跑掉。此外,如果这是 .Net 队列类型,并且您的紧密循环领先于您的异步生成以清空队列,您将抛出一个异常,该异常将跳出 while(true) block 。您可以使用如下代码解决这两个问题:

while(true)
{

    try 
    {
        String[] path =  queue.pop().Split(delimiter.ToCharArray());
        int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;

        if(process(path[0]))
        {
            Console.WriteLine("Good!");
        }
        else if (ttl > 0)
        {
            queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));             
        }
        else
        {
            Console.WriteLine("TTL expired for path: {0}" path[0]);
        }
    }
    catch(InvalidOperationException ex)
    {
        //Queue.Dequeue throws InvalidOperation if the queue is empty... sleep for a bit before trying again
        Thread.Sleep(100);
    }
}

关于c# - 动态 C# 对象的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17236141/

相关文章:

c# - Entity Framework Core - 早期的数据迁移在模型更改时中断

时间:2019-03-17 标签:c#Backgroundworkerclass

c# - 使用 Description 属性装饰 EF 对象模型上的枚举?

design-patterns - 如何打破 Grails 域类之间的硬依赖

java - 如何向上转换 Java 8 Optional 中包含的对象?

c# - 类库 COM 互操作项目的 installshield

c# - 统一场景之间的自动淡入淡出不适用于 OSX

c# - 使用带有日期时间和 bool 值的自动映射器来表示 POCO 中的半天

language-agnostic - 将成就添加到企业级软件的技术

javascript - Angular、React 和 Blaze(客户端 Meteor)之间的主要设计差异?