C# 告诉计时器对象调用其;“已过”;异步事件

C# 告诉计时器对象调用其;“已过”;异步事件,c#,asynchronous,timer,C#,Asynchronous,Timer,在我的应用程序中,有时需要手动调用计时器 我尝试了以下方法: int originalInterval = t.Interval; t.Interval = 0; t.Interval = originalInterval; 但这并不一致 我已经创建了一个新的计时器,继承自System.Timers.timer,并公开了一个“Tick”方法,但问题是“appeased”事件随后同步触发 当我用一个新线程实现“勾号”时,结果还是不一致 有没有更好的方法来实现它?我曾经遇到过同样的问题,因此我使用

在我的应用程序中,有时需要手动调用计时器

我尝试了以下方法:

int originalInterval = t.Interval;
t.Interval = 0;
t.Interval = originalInterval;
但这并不一致

我已经创建了一个新的计时器,继承自System.Timers.timer,并公开了一个“Tick”方法,但问题是“appeased”事件随后同步触发

当我用一个新线程实现“勾号”时,结果还是不一致


有没有更好的方法来实现它?

我曾经遇到过同样的问题,因此我使用AutoResetEvent来了解是否已成功调用已用事件:

/// <summary>
/// Tickable timer, allows you to manually raise a 'Tick' (asynchronously, of course)
/// </summary>
public class TickableTimer : System.Timers.Timer
{
    public new event ElapsedEventHandler Elapsed;

    private System.Threading.AutoResetEvent m_autoResetEvent = new System.Threading.AutoResetEvent(true);

    public TickableTimer()
        : this(100)
    {
    }

    public TickableTimer(double interval)
        : base(interval)
    {
        base.Elapsed += new ElapsedEventHandler(TickableTimer_Elapsed);
    }

    public void Tick()
    {
        new System.Threading.Thread(delegate(object sender)
        {
            Dictionary<string, object> args = new Dictionary<string, object>
            {
                {"signalTime", DateTime.Now},
            };
            TickableTimer_Elapsed(this, Mock.Create<ElapsedEventArgs>(args));
        }).Start();
        this.m_autoResetEvent.WaitOne();
    }

    void TickableTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        m_autoResetEvent.Set();
        if (this.Elapsed != null)
            this.Elapsed(sender, e);
    }
}
//
///可滴答的计时器,允许您手动发出“滴答声”(当然是异步的)
/// 
公共类TickableTimer:System.Timers.Timer
{
公共新事件ElapsedEventHandler已过;
private System.Threading.AutoResetEvent m_AutoResetEvent=新系统.Threading.AutoResetEvent(true);
公共TickableTimer()
:这个(100)
{
}
公共计时器(双间隔)
:基准(间隔)
{
基本运行时间+=新的ElapsedEventHandler(TickableTimer\u运行时间);
}
公共空白勾号()
{
新System.Threading.Thread(委托(对象发送器)
{
Dictionary args=新字典
{
{“signalTime”,DateTime.Now},
};
TickableTimer_已过(这是Mock.Create(args));
}).Start();
这个.m_autoResetEvent.WaitOne();
}
void TickableTimer_已过(对象发送器,ElapsedEventArgs e)
{
m_autoResetEvent.Set();
如果(this.appeased!=null)
此。已过(发送方,e);
}
}

通常,您不需要手动启动计时器-您可以始终在新线程中运行事件本身。总的来说,这基本上就是计时器所做的,因为您想要手动启动它,所以不需要计时器(用于手动调用)

您没有详细说明“不一致”的含义。以下各项应正常工作:

Thread thread = new Thread(myDelegate);
thread.Start();
当然,
myDelegate
可以是lambda,以防需要传递参数:

Thread thread = new Thread(() => myMethod(param1, param2));
thread.Start();

感觉上你应该看看你的设计。通常,我会尽量避免让事件处理程序方法包含正在完成的实际工作,但我会尽量让它只是一个触发器,调用执行该工作的其他方法。这样,您也可以从任何其他位置调用该其他方法:

private void Timer_Tick(object sender, EventArgs e)
{
    new Thread(MethodThatDoesTheWork).Start();
}

private void MethodThatDoesTheWork()
{
    // actual work goes here
}
现在,您可以从类中的任何其他位置(使用单独的线程同步或异步)调用执行工作的
方法

或者,如果执行该工作的
方法应始终是异步调用,则可以在该方法内生成线程:

private void MethodThatDoesTheWork()
{
    new Thread(() =>
    {
         // work code goes here
    }).Start();
}

在这些示例中,我手动创建了线程。您可以使用这种方法,
线程池
任务
或任何其他异步调用代码的方法,以最适合您的上下文的方法为准。

我尝试过这种方法,但结果总是不一致。。。特别是当用户称为“勾选”的时候times@Fliskov当前位置说“它是不一致的”现在和你的问题中一样没用了。有什么细节吗?看看@FredreckI的注释,我用的是'Moke',因为它的构造函数是私有的,哪个命名空间包含Mock?这是我创建的自定义帮助器类。改为使用以下命令:
System.Timers.ElapsedEventArgs ea=(ElapsedEventArgs)System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(ElapsedEventArgs));typeof(ElapsedEventArgs).GetField(“signalTime”,BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ea,DateTime.Now);TickableTimer_已过(此,ea)勾选
事件并不能解决问题。我的建议是完全避免引用它。也许您可以详细说明一下您的代码在问题中实际做了什么(这将更容易提供有用的答案)?结果在哪些方面不一致?1。由于使用thread.Start而不是ThreadPool.Queue(我不想使用它…太难看),线程已关闭。当用户多次调用“Tick”(在方法停止之前)时,我希望它每次都等待第一次调用完成,然后才调用它