0

我正在开发一个通过 WMI 查询服务器状态的应用程序,我被要求使其自动循环,并且它可以将查询排队以每隔一段时间获取几台服务器的状态。我遇到的问题是,在创建第一个计时器时建立的值在第二个计时器(如服务器名称和查询类型)时发生了变化。这是代码的一部分:

public System.Threading.Timer[] schedquery = new System.Threading.Timer[10];
private void button1_Click(object sender, EventArgs e)
    {
        schedquery[C3MonitorApp.globalVars.tmrArray] = new System.Threading.Timer(writeLog);
        schedValues.schedTurns = 120 / schedValues.schedTimer;
        schedquery[C3MonitorApp.globalVars.tmrArray].Change(1000, 0);
        C3MonitorApp.globalVars.tmrArray++;
    }

    public void writeLog(object state)
    {
        //do queries and write results to file then check if the timer
        //has done certain amount of loops and dispose or restart
        schedValues.schedTurnCounter++;
        if (schedValues.schedTurnCounter == schedValues.schedTurns)
        {
            this.Dispose();
        }
        else
        {

            System.Threading.Timer t = (System.Threading.Timer)state;
            t.Change(1000 * 60 * schedValues.schedTimer, 0);

        }
    }

写入日志函数从公共类获取服务器名称和查询类型,因此我希望以某种方式存储服务器名称等这些值,以便计时器使用原始值而不是用于创建第二个、第三个或第四个计时器。

问候。

4

1 回答 1

1

state传递给计时器的对象是state您传递给构造函数的参数。考虑到您的代码没有传递state参数,我对您的代码完全有效感到有些惊讶。这意味着您的代码else应该因无效的强制转换或空引用异常而失败。

很难确定,因为您的问题有点模糊,但我认为您想要的是创建一个状态对象并将其传递给构造函数。例如:

class TimerState
{
    public string ServerName { get; set; }
    public string QueryType { get; set; }
    public int TimerIndex { get; set; }
}

private void button1_Click(object sender, EventArgs e)
{
    schedValues.schedTurns = 120 / schedValues.schedTimer;
    var stateObj = new TimerState
        { ServerName = "foo", QueryType = "bar", TimerIndex = C3MonitorApp.globalVars.tmrArray };
    schedquery[C3MonitorApp.globalVars.tmrArray] =
        new System.Threading.Timer(writeLog, stateObj, 1000, 0);
    C3MonitorApp.globalVars.tmrArray++;
}

并改变你的writeLog

public void writeLog(object state)
{
    TimerState stateObj = (TimerState)state;
    Timer t = schedquery[stateObj.TimerIndex];

    //do queries and write results to file then check if the timer
    //has done certain amount of loops and dispose or restart
    schedValues.schedTurnCounter++;
    if (schedValues.schedTurnCounter == schedValues.schedTurns)
    {
        t.Dispose();
    }
    else
    {
        t.Change(1000 * 60 * schedValues.schedTimer, 0);
    }
}

我很确定你不想处置this. 正如我在这里展示的那样,您想要处置计时器。

我可能会遗漏一些关于您的应用程序细节的信息,但以上内容将为您提供大致的思路。

于 2013-05-20T20:33:27.993 回答