【问题标题】:Delegate to an instance method cannot have null Intermittent on runtime委托给实例方法在运行时不能有 null 间歇
【发布时间】:2015-06-04 11:37:42
【问题描述】:

我收到此错误,无法理解此错误。 我使用 win 表格和 .net 3.5。 问题是,这可以编译和间歇性的。今天刚刚展示,所以我猜这种情况非常罕见(可能在 5000 次运行后出现)。我想知道是什么导致了这个错误,以及任何可能的解决方法。 这是我如何实现代码的示例。

我的应用是多线程的,这个方法是单例的。


Exception type: System.ArgumentException
Exception message: Delegate to an instance method cannot have null 'this'.
Exception stack trace: 
   at System.MulticastDelegate.ThrowNullThisInDelegateToInstance()
   at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr)

  class Caller
  {
    private ClassA theA;
    public Caller()
    {
      theA = new ClassA();
    }

    public void button_click()
    {
      theA.Execute(false);
    }
    public void button2_click()
    {
      theA.Execute( true );
    }
  }

  interface IClassA
  {
    void ActionMinus();
  }
  class ClassA
  {
    public int VariableA = 0;
    public void Execute( bool wait )
    {
      ClassB instanceB = new ClassB( this );
      Thread thread = new Thread( instanceB.Action ) // error in here
      { 
        Name = "Executor",
        Priority = ThreadPriority.Highest
      };

      thread.Start();
      if( wait )
        thread.Join();
    }
    public void ActionMinus()
    {
      //someAction1
      VariableA -= 2;
      //someAction2
    }
  }

  class ClassB
  {
    private readonly ClassA instanceA;
    public ClassB( ClassA instance )
    {
      instanceA = instance;
    }
    public void Action()
    {
      //some other action3
      instanceA.VariableA += 5;
      //some other action4
      instanceA.ActionMinus();
      //some other action5
    }
  }

【问题讨论】:

  • 请提供重现问题的a good, minimal, complete code example(即使是间歇性的)。到目前为止,您的帖子暗示 instanceB 在创建线程委托时是 null,但这里没有什么可以做到这一点。缺少完整的代码示例,很难猜出实际问题是什么。
  • 首先你确实有很多编译错误,比如在ActionMinus 之前缺少返回类型@ClassB 之前缺少类关键字等等......解决它,你会得到很好的工作代码.
  • 编辑代码@PeterDuniho,我相信instanceB不为空。

标签: c# delegates


【解决方案1】:

它看起来对我有用。

你的程序的上下文是什么?

我写了一个简单的空壳包含你的代码,但程序将在线程启动之前结束。

我必须添加一个 Console.ReadKey() 方法。

这是我使用的全部代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace DelegateToInstance {

  class Program {
    static void Main(string[] args) {
      var obj = new Caller();
      obj.button_click();
      Console.ReadKey();
    }
  }

  class Caller
  {
    private ClassA theA;
    public Caller()
    {
      theA = new ClassA();
    }

    public void button_click()
    {
      theA.Execute(false);
    }
    public void button2_click()
    {
      theA.Execute( true );
    }
  }

  interface IClassA
  {
    void ActionMinus();
  }

  class ClassA
  {
    public int VariableA = 0;
    public void Execute( bool wait )
    {
      ClassB instanceB = new ClassB(this);
      Thread thread = new Thread( instanceB.Action ) // error in here
      { 
        Name = "Executor",
        Priority = ThreadPriority.Highest
      };

      thread.Start();
      if( wait )
        thread.Join();
    }
    public void ActionMinus()
    {
      //someAction1
      VariableA -= 2;
      //someAction2
    }
  }

  class ClassB
  {
    private readonly ClassA instanceA;
    public ClassB( ClassA instance )
    {
      instanceA = instance;
    }
    public void Action()
    {
      //some other action3
      instanceA.VariableA += 5;
      //some other action4
      instanceA.ActionMinus();
      //some other action5
    }
  }

}

我讨厌投反对票的人,所以我给了你一票。

【讨论】:

  • 谢谢 jp。我看不到你的屏幕截图。是的,代码通常可以工作,但昨天我遇到了间歇性错误。这是我第一次看到它,我无法重现它。我不明白为什么它会抛出这个错误。
  • ClassB 用于向硬件发送命令。程序首先结束,因为我们只使用简单的命令。如果使用 win 表单,点击按钮后,它将向硬件发送命令,并且 UI 仍然可以访问。
  • 如果程序先结束,那会导致你的空引用异常。您可能需要使用ManualResetEvent control 来确保您的对象在您完成之前保持活动状态。
  • 看来我因支持您的投票而遭到反对。给我点个赞,让我们的净值为 0。
  • 你显然并不孤单。这是另一个链接,这个在 MSDN 上:Why do I need a null test before I invoke a delegate?
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
相关资源
最近更新 更多