调用初始化的(非null)委托会产生NullReferenceException(在Windows服务中)

本文关键字:NullReferenceException Windows 服务 初始化 null 调用 | 更新日期: 2024-09-23 08:52:13

由于某些原因,我很难从Windows服务的线程中调用委托方法。不要认为环境会带来太大的不同,但希望您理解为什么我不能在调试器中直接遍历这些代码(不过跟踪日志记录是很可能的)。以下是一个简化的大纲;我只想从主类执行一个回调来处理接收到的数据(我的愿望是将数据处理实现[涉及太多其他依赖项]与BaseSvc的库代码分离):

public class    BaseSvc         // library class (separate DLL)
{
    public delegate     bool    dlProcCmd( byte[] bData );
    public static   dlProcCmd   fnProcCmd;
    public static void      Start( )                                // 1
//  public static void      Start( BaseSvc.dlProcCmd ProcCmd )      // 2
    {
//      BaseSvc.fnProcCmd=  ProcCmd;                                // 2
        ..
        bListen=    true;
        thTcpComm=  new Thread( new ThreadStart( TcpComm ) );
        thTcpComm.Start( );
    }
    ..
    public static void      TcpComm( )
    {
        ..
        while(  bListen  )
        {
            ..
            if(  fnProcCmd != null  )
            {
                Utils.Log( fnProcCmd.Method.ToString( ) );
                    // prints:Boolean ProcCmd(Byte[])
                fnProcCmd( bData );     // throws:
                    // Void TcpComm():  System.NullReferenceException
                    // Object reference not set to an instance of an object.
            }
        }
    }
    ..
}

public partial class    WinSvc : ServiceBase        // SCM-compatible .exe
{
    /// <summary>Handles Start command</summary>
    protected override void     OnStart( string[] args )
    {
        BaseSvc.fnProcCmd=  ProcCmd;                                // 1a
//      BaseSvc.fnProcCmd=  new BaseSvc.dlProcCmd( ProcCmd );       // 1b
//      BaseSvc.fnProcCmd+= new BaseSvc.dlProcCmd( ProcCmd );       // 1c
        BaseSvc.Start( );                                           // 1
//      BaseSvc.Start( new BaseSvc.dlProcCmd( ProcCmd ) );          // 2
        ..
    }
    public bool     ProcCmd( byte[] bData )
    {
        ..
        return  true;
    }
}

起初,我认为smth对委托方法的声明或初始化是错误的,所以各种尝试都用1a、1b、1c和2标记。然而,在任何一种情况下,我都会得到一个跟踪打印输出,确认if( fnProcCmd != null )检查通过,然后是NullRefExceptionbData参数在那一刻被初始化,通过跟踪100%保证和确认,因此只留下fnProcCmd作为罪魁祸首。但是它已经初始化了,不是吗!?我在这里错过了什么??

是否可能是WinSvc类的执行上下文与BaseSvc的执行上下文不同,和/或TcpComm( )在自己的线程中执行?我希望在这种情况下会出现更直观的错误。。

我一定做错了。我应该怎么做才能启用这样的回调?

UPDATE:在Henk的建议之后,我注释掉了ProcCmd的主体,问题消失了,=>问题在该代码中,与委托机制无关。抱歉弄糊涂了
(顺便说一句,通过场景1a使用委托很好。)

调用初始化的(非null)委托会产生NullReferenceException(在Windows服务中)

查看此部分:

        if(  fnProcCmd != null  )
        {
            Utils.Log( fnProcCmd.Method.ToString( ) );
                // prints:Boolean ProcCmd(Byte[])
            fnProcCmd( bData );     // throws:
                // Void TcpComm():  System.NullReferenceException
                // Object reference not set to an instance of an object.
        }

fnProcCmd上的空检查是广泛而令人信服的,所以它一定是ProcCmd()内部发生的事情。

要了解错误,请使用空的ProcCmd():进行尝试

 public bool     ProcCmd( byte[] bData )
 {
    //    ...
    //
    //    ...
    return  true;
 }