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);
}
}
}