紧凑型定时器声明

时间:2021-02-18 09:49:37

标签: c# wpf

我有一个桌面 WPF 应用程序,在某些时候需要及时执行某些操作。假设我使用 DispatcherTimer 类。有一条“很长”的路:

public MainWindow()
{
    // dozens lines of code

    timer1.Interval = new TimeSpan(0, 0, 1);
    timer1.Tick += timer1_Tick;
}

// hundreds lines of code later

DispatcherTimer timer1 = new DispatcherTimer();

void timer1_Tick(object sender, EventArgs e)
{
    // do stuff
}

void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    timer1.IsEnabled = checkBox1.IsChecked.Value;
}

它工作正常,但我不喜欢将与计时器相关的代码分成两部分。每次启动时我都可以重新创建计时器:

DispatcherTimer timer1;

void timer1_Tick(object sender, EventArgs e)
{
    // do stuff
}

void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    timer1 = new DispatcherTimer();
    timer1.Interval = new TimeSpan(0, 0, 1);
    timer1.Tick += timer1_Tick;
    timer1.IsEnabled = checkBox1.IsChecked.Value;
}

但感觉不对。 DispatcherTimer 也有将 EventHandler 作为参数的构造函数,我可以像这样使用:

DispatcherTimer timer1 = new DispatcherTimer(
    new TimeSpan(0,0,1),
    DispatcherPriority.SystemIdle,
    new EventHandler(timer1_Tick),
    Dispatcher.CurrentDispatcher);

void timer1_Tick(object sender, EventArgs e)
{
    // do stuff
}

void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    timer1.IsEnabled = checkBox1.IsChecked.Value;
}

我喜欢它,它既简单又紧凑,但你不能用这种方式创建 EventHandler,编译器说“字段初始化程序不能引用非静态字段、方法或等等”。

有没有办法让这个漂亮的代码真正起作用?

3 个答案:

答案 0 :(得分:1)

在构造函数中完成所有操作有什么问题?这就是我通常这样做的方式:

private DispatcherTimer _timer1;

public MainWindow()
{
    // dozens lines of code
    _timer1 = new DispatcherTimer(TimeSpan.FromSeconds(1), 
                                  DispatcherPriority.SystemIdle,
                                  timer1_Tick,
                                  Dispatcher);
}

答案 1 :(得分:0)

如果您不介意将字段更改为属性(带有支持字段),您可以在 getter 中进行初始化(仅在第一次读取时):

from paho.mqtt.client import Client
import json

from app import create_app
from app.models import db

from app.models import Monitoring


app = create_app()


class CustomClient(Client):

    def add_reading(self, reading):
        with app.app_context():
            db.session.add(reading)
            db.session.commit()

    def on_connect(self, client, userdata, flags, rc):
        print(
            "Connected:", 
            str(client._host) + ":" + str(client._port)
        )

    def on_subscribe(self, mqttc, obj, mid, granted_qos):
        print(
            "Subscribed:", 
            str(mid), str(granted_qos)
        )

    def on_message(self, client, userdata, message):
        msg = message.payload.decode()
        print(message.topic, msg)
        data = json.loads(msg)
        reading = Monitoring(**data)

        self.add_reading(reading)

    def run(self):
        self.connect("localhost", 1883, 60)
        self.subscribe("Main/#", 0)

        self.loop_forever()

答案 2 :(得分:0)

您可以改为在构造函数中创建计时器。可选择使用本地函数或 lambda 来让处理程序保持接近初始化。

如果您遵循 stylecop code style rules,代码应按以下顺序订购

  • 字段
  • 构造函数
  • ...
  • 方法

因此,如果在定时器的声明和初始化之间有数百行代码,那么您可能需要首先解决其他设计问题。

如果你有多个构造函数,你应该有一个保证运行的构造函数,并且所有其他的构造函数都委托一些构造函数。