gpt4 book ai didi

c# - 如何运行分配给模拟的事件处理程序?

转载 作者:可可西里 更新时间:2023-11-01 07:56:10 24 4
gpt4 key购买 nike

我正在尝试触发分配给我的计时器模拟的事件处理程序。我如何在这里测试这个私有(private)方法?

public interface ITimer
{
void Start();
double Interval { get; set; }
event ElapsedEventHandler Elapsed;
}

客户端类为该对象分配一个事件处理程序。我想测试这个类中的逻辑。

_timer.Elapsed += ResetExpiredCounters;

并且分配的方法是私有(private)的

private void ResetExpiredCounters(object sender, ElapsedEventArgs e)
{
// do something
}

我想在我的模拟中拥有这个事件处理程序并以某种方式运行它。我该怎么做?

更新:

我意识到我在分配事件处理程序之前引发了事件。我更正了,但我仍然收到此错误:

System.ArgumentException : Object of type 'System.EventArgs' cannot be converted 
to type 'System.Timers.ElapsedEventArgs'.

我是这样提出来的:

_timer.Raise(item => item.Elapsed += null, ElapsedEventArgs.Empty);

_timer.Raise(item => item.Elapsed += null, EventArgs.Empty);

两者都行不通。

更新:

这是对我有用的东西。请注意,如果您尝试将信息传递给 Jon 在评论中指出的事件处理程序,则它没有用。我只是用它来模拟 System.Timers.Timer 类的包装器。

_timer.Raise(item => item.Elapsed += null, new EventArgs() as ElapsedEventArgs);

最后,如果您需要使用事件参数,这将毫无帮助,因为它始终为空。但是,这是唯一的方法,因为 ElapsedEventArgs 只有一个内部构造函数。

最佳答案

ElapsedEventArgs 有一个私有(private)的构造函数,不能被实例化。

如果您使用:

timer.Raise(item => item.Elapsed += null, new EventArgs() as ElapsedEventArgs);

然后处理程序将收到一个空参数并丢失其 SignalTime 属性:

private void WhenTimerElapsed(object sender, ElapsedEventArgs e)
{
// e is null.
}

在某些情况下您可能需要此参数。

为了解决这个问题并使其更易于测试,我还为 ElapsedEventArgs 创建了一个包装器,并让接口(interface)使用它:

public class TimeElapsedEventArgs : EventArgs
{
public DateTime SignalTime { get; private set; }

public TimeElapsedEventArgs() : this(DateTime.Now)
{
}

public TimeElapsedEventArgs(DateTime signalTime)
{
this.SignalTime = signalTime;
}
}

public interface IGenericTimer : IDisposable
{
double IntervalInMilliseconds { get; set; }

event EventHandler<TimerElapsedEventArgs> Elapsed;

void StartTimer();

void StopTimer();
}

该实现将简单地触发它自己的事件,从实时计时器事件中获取数据:

public class TimerWrapper : IGenericTimer
{
private readonly System.Timers.Timer timer;

public event EventHandler<TimerElapsedEventArgs> Elapsed;

public TimeSpan Interval
{
get
{
return this.timer.Interval;
}
set
{
this.timer.Interval = value;
}
}

public TimerWrapper (TimeSpan interval)
{
this.timer = new System.Timers.Timer(interval.TotalMilliseconds) { Enabled = false };
this.timer.Elapsed += this.WhenTimerElapsed;
}

private void WhenTimerElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
{
var handler = this.Elapsed;
if (handler != null)
{
handler(this, new TimeElapsedEventArgs(elapsedEventArgs.SignalTime));
}
}

public void StartTimer()
{
this.timer.Start();
}

public void StopTimer()
{
this.timer.Stop();
}

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.timer.Elapsed -= this.WhenTimerElapsed;
this.timer.Dispose();
}

this.disposed = true;
}
}
}

现在,您可以简化和改进此事件的模拟:

timer.Raise(item => item.Elapsed += null, new TimeElapsedEventArgs());

var yesterday = DateTime.Now.AddDays(-1);
timer.Raise(item => item.Elapsed += null, new TimeElapsedEventArgs(yesterday));

编写的代码更少,更易于使用,并且与框架完全分离。

关于c# - 如何运行分配给模拟的事件处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8940982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com