You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#控制台程序编译报错:非静态字段_timer需对象引用,求解决方案

解决C#静态方法访问非静态字段的定时器错误

错误原因

An object reference is required for the non-static field, method, or property "Program._timer"

这个错误的核心是静态方法无法直接访问类的非静态成员:Main是静态方法,属于类本身;而_timer是类的实例字段,属于类的具体对象。两者上下文不同,所以静态方法里直接给_timer赋值会编译失败。

同时你代码里还有一个逻辑问题:mre.WaitOne()放在了定时器初始化代码之前,程序会先阻塞在这里,永远不会执行到创建定时器的步骤,必须调整顺序。


解决方案一:将_timer改为静态字段

最简单的修改方式是把_timer声明为静态字段,让它和Main方法同属静态上下文:

using System;
using System.Xml.Linq;
using Microsoft.Win32;
using static Microsoft.Win32.SystemEvents;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Diagnostics.Metrics;
using System.Timers;
using System.Threading;

namespace CSharpTutorials
{
    class Program
    {
        // 修改为静态字段
        private static System.Threading.Timer _timer = null;
        
        public static void Main()
        {
            DateTime lastLogin, lastLock;
            string bossEmail;

            XDocument doc = XDocument.Load("properties.xml");
            XElement lastLockElement = doc.Descendants("lastLock").FirstOrDefault();
            XElement lastLoginElement = doc.Descendants("lastLogin").FirstOrDefault();
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
           
            var mre = new ManualResetEvent(false);
            Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
            {
                mre.Set();
            };

            // 先初始化定时器,再阻塞等待退出信号
            _timer = new System.Threading.Timer(TimerCallback, null, 0, 2000);
            
            mre.WaitOne();
        }
        
        private static void TimerCallback(Object o)
        {
            Console.WriteLine("In TimerCallback: " + DateTime.Now);
        }
        
        public static string GetTimestamp(DateTime value)
        {
            return value.ToString("yyyy/MM/dd HH:mm:ss");
        }
        
        static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            string timeStamp = GetTimestamp(DateTime.Now);
            XDocument doc = XDocument.Load("prefrences.xml");

            switch (e.Reason)
            {
                case SessionSwitchReason.SessionLogon:
                    XElement logonElement = doc.Descendants("lastLogin").FirstOrDefault();
                    if (logonElement != null)
                    {
                        logonElement.SetAttributeValue("lastLogin", DateTime.Now);
                        doc.Save("properties.xml");
                    }
                    break;
                case SessionSwitchReason.SessionLock:
                    XElement lockElement = doc.Descendants("lastLock").FirstOrDefault();
                    if (lockElement != null)
                    {
                        lockElement.SetAttributeValue("lastLock", DateTime.Now);
                        doc.Save("properties.xml");
                    }
                    break;
                case SessionSwitchReason.SessionLogoff:
                case SessionSwitchReason.RemoteConnect:
                case SessionSwitchReason.RemoteDisconnect:
                case SessionSwitchReason.SessionUnlock:
                default:
                    break;
            }
        }
    }
}

解决方案二:使用类实例访问非静态字段

如果希望保持_timer为实例字段,可以创建Program类的对象,通过对象访问字段:

using System;
using System.Xml.Linq;
using Microsoft.Win32;
using static Microsoft.Win32.SystemEvents;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Diagnostics.Metrics;
using System.Timers;
using System.Threading;

namespace CSharpTutorials
{
    class Program
    {
        private System.Threading.Timer _timer = null;
        
        public static void Main()
        {
            DateTime lastLogin, lastLock;
            string bossEmail;

            XDocument doc = XDocument.Load("properties.xml");
            XElement lastLockElement = doc.Descendants("lastLock").FirstOrDefault();
            XElement lastLoginElement = doc.Descendants("lastLogin").FirstOrDefault();
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
           
            var mre = new ManualResetEvent(false);
            Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
            {
                mre.Set();
            };

            // 创建Program实例
            Program app = new Program();
            // 通过实例初始化定时器
            app._timer = new System.Threading.Timer(app.TimerCallback, null, 0, 2000);
            
            mre.WaitOne();
        }
        
        // 修改为非静态方法
        private void TimerCallback(Object o)
        {
            Console.WriteLine("In TimerCallback: " + DateTime.Now);
        }
        
        public static string GetTimestamp(DateTime value)
        {
            return value.ToString("yyyy/MM/dd HH:mm:ss");
        }
        
        static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            string timeStamp = GetTimestamp(DateTime.Now);
            XDocument doc = XDocument.Load("prefrences.xml");

            switch (e.Reason)
            {
                case SessionSwitchReason.SessionLogon:
                    XElement logonElement = doc.Descendants("lastLogin").FirstOrDefault();
                    if (logonElement != null)
                    {
                        logonElement.SetAttributeValue("lastLogin", DateTime.Now);
                        doc.Save("properties.xml");
                    }
                    break;
                case SessionSwitchReason.SessionLock:
                    XElement lockElement = doc.Descendants("lastLock").FirstOrDefault();
                    if (lockElement != null)
                    {
                        lockElement.SetAttributeValue("lastLock", DateTime.Now);
                        doc.Save("properties.xml");
                    }
                    break;
                case SessionSwitchReason.SessionLogoff:
                case SessionSwitchReason.RemoteConnect:
                case SessionSwitchReason.RemoteDisconnect:
                case SessionSwitchReason.SessionUnlock:
                default:
                    break;
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Zac Borders

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 22:35:19