共享库进度/状态消息

时间:2014-05-08 10:57:41

标签: c# architecture software-design

我有一个方法,可以做一些需要一段时间的事情并发回进度/状态消息。该方法曾经是我的控制台Main()类中的Program静态方法。后来,我决定将功能转移到共享库程序集中,以便新的web api项目可以访问相同的功能,因此具有不同stdio机制的不同用户界面。

在移动的方法中替换所有Console.Writeline()调用的好设计模式是什么?

我正在考虑添加一个可观察的集合(字符串)来存储消息,然后让任何调用程序集订阅集合上的更改并实现他们自己的ui机制来显示消息回到用户。

这是否合理还是重新发明轮子?框架中是否已经有一个专门构建的方法来处理这样的场景?

编辑:

感谢@astef,我实现了它:

public interface IMessageObserver
{
    void Notify(string message);
    void Notify(string format, params object[] args);
}

public class ConsoleMessageObserver : IMessageObserver
{
    public void Notify(string message)
    {
        Console.WriteLine(message);
    }

    public void Notify(string format, params object[] args)
    {
        Console.WriteLine(format, args);
    }
}

class Program
{
    static void Main()
    {
        Library.LongRunningMethod(new ConsoleMessageObserver());
    }
}

static class Library
{
    public static void LongRunningMethod(IMessageObserver observer)
    {
        observer.Notify("Some progress happened...");
    }
}

2 个答案:

答案 0 :(得分:1)

如果您需要有人来处理您的进度消息,请定义它:

public interface IProgressObserver
{
    void NotifyProgress(double done);
}

并使用:

public void YourLongRunningMethod(IProgressObserver progressObserver)
{
    // ...

    progressObserver.NotifyProgress(1d);
}

现在,您可以更具体地了解谁将实际处理此消息。例如:

public class ConsoleProgressObserver : IProgressObserver
{
    public void NotifyProgress(double done)
    {
        Console.WriteLine("Progress: {0:0.00}%", done * 100);
    }
}

这是Windows 98系统中使用的一个;)

public class StuckingProgressObserver : IProgressObserver
{
    private const double stucksAfter = 0.95;

    private readonly IProgressObserver wrapee;

    public StuckingProgressObserver(IProgressObserver wrapee)
    {
        this.wrapee = wrapee;
    }

    public void NotifyProgress(double done)
    {
        if (done < stucksAfter)
        {
            wrapee.NotifyProgress(done);
        }
    }
}

答案 1 :(得分:0)

使用像@astef建议的事件是一个好主意,但他们的代码不是惯用的C#。 .NET直接支持委托,因此不需要一个方法接口。

在C#中,我们定义了一个class ProgressChangedEventArgs : EventArgs,然后将EventHandler<ProgressChangedEventArgs> ProgressChanged添加到生成该事件的类中。

实际上,框架已经包含System.ComponentModel命名空间中的那些。