无法访问非静态字段&lblSystemStatus'在静态环境中

时间:2015-11-16 09:56:46

标签: c# multithreading winforms user-controls

我见过很多关于这个问题的帖子,其中没有一个有帮助。 我有以下简单的代码:

private delegate void UpdateLabelCallback(Label lbLabel, string val);

防止非法交叉线程调用的简单委托。

private static readonly System.Threading.Timer TimerHalfASecond = new System.Threading.Timer(HalfASecondCallback, null,
        500, Timeout.Infinite);

线程计时器

private static void HalfASecondCallback(object state)
{
    UpdateLabel(lblSystemStatus, Resources.DesktopClock_timerOneSecond_Tick_CPU__ + _cpu.GetCpuCounter().ToString() + @"%");
    TimerHalfASecond.Change(500, Timeout.Infinite);
}

静态Threading.Timer回调。 lblSystemStatus显示错误

  

"无法访问非静态字段&lblSystemStatus'在静态环境中"

private static void UpdateLabel(Label lbLabel, string val)
{
    if (lbLabel.InvokeRequired)
    {
        var d = new UpdateLabelCallback(UpdateLabel);
        lbLabel.Invoke(d, lbLabel, val);
    }
    else
    {

        lbLabel.Text = val;
    }
}

静态UpdateLabel方法。

所以问题是: 当控件上的标签不是静态的并且回调要求它们是什么时,我如何更新控件上的标签?

2 个答案:

答案 0 :(得分:1)

您将计时器声明为private static readonly。如果计时器在类(控件)的实例中运行,我不会这样做。如果你没有使它static,那么其他方法就没有了,你可以安全地使用实例变量(如果你有两个类实例,那么计时器可能会发生冲突)。

另一种方法是向state构造函数提供Timer以包含标签,或者Func<Label来检索标签。对于第一个选项,这意味着您必须延迟创建计时器,直到创建标签。

样品:

new System.Threading.Timer(HalfASecondCallback, this.lblStatusText,
    500, Timeout.Infinite);

然后你的处理程序可能是:

private static void HalfASecondCallback(object state)
{
    Label l = state as Label; // in fact lblSystemStatus

    if (l != null)
    {
        UpdateLabel(l, Resources.DesktopClock_timerOneSecond_Tick_CPU__ + _cpu.GetCpuCounter().ToString() + @"%");
        TimerHalfASecond.Change(500, Timeout.Infinite);
    }
}

答案 1 :(得分:0)

您可以创建一些静态字段,将标签分配给此字段并在静态上下文中使用