C# 共享库进度/状态消息

C# 共享库进度/状态消息,c#,architecture,software-design,C#,Architecture,Software Design,我有一个方法,可以做一些需要花费一些时间的事情,并将进度/状态消息发回。该方法以前是我的控制台程序类中的Main()静态方法。后来,我决定将该功能移到一个共享库程序集中,以便新的WebAPI项目可以访问相同的功能,从而为stdio提供具有不同机制的不同用户界面 用什么好的设计模式来替换moved方法中的所有Console.Writeline()调用 我正在考虑添加一个可观察的集合(字符串)来存储消息,然后让任何调用程序集订阅集合上的更改,并实现它们自己的ui机制来向用户显示消息 这是合理的还是重

我有一个方法,可以做一些需要花费一些时间的事情,并将进度/状态消息发回。该方法以前是我的控制台
程序
类中的
Main()
静态方法。后来,我决定将该功能移到一个共享库程序集中,以便新的WebAPI项目可以访问相同的功能,从而为stdio提供具有不同机制的不同用户界面

用什么好的设计模式来替换moved方法中的所有
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...");
    }
}

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

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系统中使用的;)

公共类StuckingProgressObserver:IProgressObserver
{
私人常数双stucksAfter=0.95;
私有只读IProgressObserver wrapee;
公众观察者(IProgressObserver-wrapee)
{
this.wrapee=wrapee;
}
公共进度(完成两次)
{
如果(完成
使用事件,如@astef建议的是一个好主意,但他们的代码不是惯用的C#。NET直接支持委托,因此不需要单一方法接口

在C#中,我们将定义一个
类ProgressChangedEventArgs:EventArgs
,然后向生成事件的类添加一个
EventHandler ProgressChanged


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

添加一个事件怎么样?这样,主程序(或日志客户端)就可以订阅事件,并根据需要格式化、显示或记录状态事件。这非常优雅,效果也很好。谢谢我稍微修改了一下,因为我对消息字符串而不是完成百分比感兴趣,但这是一种非常简单有效的模式。我喜欢@astef的解决方案,主要是因为它不是基于事件的。one method界面实际上看起来相当优雅(对我来说),因为它只公开了我想要的功能(用
observer.Notify()
替换
Console.Writeline()
),并允许我以任何适当的方式实现UI消息传递。我希望
Console
已经是某个UI交互界面的实现,这样就不需要我自己的界面了。@glandate我认为以消息字符串形式发送进度的库是错误的抽象级别。在大多数情况下,库应该引发调用应用程序理解的事件,而不是应用程序仅通过的字符串。
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);
        }
    }
}