Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 几秒钟后TimeSetEvent失败(NullReferenceException)_C#_Timer_Callback_Nullreferenceexception - Fatal编程技术网

C# 几秒钟后TimeSetEvent失败(NullReferenceException)

C# 几秒钟后TimeSetEvent失败(NullReferenceException),c#,timer,callback,nullreferenceexception,C#,Timer,Callback,Nullreferenceexception,我正在使用TimeSetEvent,其回调函数正在工作,但几秒钟后,即使回调函数根本不工作,它也会失败: // Vars private TimerEventHandler timerRef; private uint timerId = 0; //Later, where I use TimeSetEvent timerRef = new TimerEventHandler(CallbackFunction); timerId = timeSetEvent(200, 10, timerRef

我正在使用TimeSetEvent,其回调函数正在工作,但几秒钟后,即使回调函数根本不工作,它也会失败:

// Vars
private TimerEventHandler timerRef;
private uint timerId = 0;

//Later, where I use TimeSetEvent
timerRef = new TimerEventHandler(CallbackFunction);
timerId = timeSetEvent(200, 10, timerRef, UIntPtr.Zero, TIME_KILL_SYNCHRONOUS | TIME_PERIODIC);
即使有200毫秒的延迟,它也不能正常工作

private void CallbackFunction(uint id, uint msg, UIntPtr userCtx, UIntPtr uIntPtr, UIntPtr intPtr)
{

// Even if this is empty, it will fail
}
我要么得到NullReferenceException(大多数时候),要么得到AccessViolationException(偶尔)。我怀疑两者都来自同一个问题

有趣的是,我在另一个类中有完全相同的结构,它可以工作。我抄了那门课,在这里。。。没有。我得到这个错误

我不明白为什么它不起作用(在另一门课上也是如此),以及如何解决它


PD:timerId返回一个不同于0的整数。如果我注释
TimerId=TimeSetEvent
,我不明白这个空值从何而来。。。代码不会失败。

几天后,我的同事审查了越来越多的代码,我们发现了问题。不得不说这个问题没有足够的信息来解决,但我们不知道。这是一个非常复杂的程序,我们无法想象我们需要其他类的代码

上述代码属于
B类
。这是从
A类
调用的。结果是,
A类
偶尔会被破坏,而
TimeSetEvent
被pinvoke(非托管)时,它会继续工作。因此,当它试图查找回调函数时,它已与
类B
中的所有内容一起被释放,并给出一个空引用异常


解决方案是在
类别B
中实现一种方法,该方法在删除
类别a
之前终止计时器。然后,可以安全地删除
A类
,而
B类
不会使应用程序崩溃。

几天后,我的同事查看了越来越多的代码,我们发现了问题。不得不说这个问题没有足够的信息来解决,但我们不知道。这是一个非常复杂的程序,我们无法想象我们需要其他类的代码

上述代码属于
B类
。这是从
A类
调用的。结果是,
A类
偶尔会被破坏,而
TimeSetEvent
被pinvoke(非托管)时,它会继续工作。因此,当它试图查找回调函数时,它已与
类B
中的所有内容一起被释放,并给出一个空引用异常


解决方案是在
类别B
中实现一种方法,该方法在删除
类别a
之前终止计时器。然后,可以安全地删除
类A
,而
类B
不会使应用程序崩溃。

它在哪一行代码中抛出该异常?它没有说明,因此我找不到它。然而,我对所有代码进行了注释,并一个接一个地添加函数,并意识到当我调用这个TimeSetEvent时,它将在大约20次迭代后很快崩溃。即使函数什么也不做。然而,不称之为“工作”(=不会崩溃,但显然我需要那个计时器)。timeSetEvent做什么?它就像计时器一样。计时器更精确。它被称为定时器多媒体,具有可编辑的高精度,适用于高达1ms的windows)。如果您不向我们展示一个计时器,我们将无法回答。我怀疑这个问题是由一个托管对象引起的,该对象被gc删除或移动。考虑将TimeReEvEndEnter保持在范围内,或者将其封装在<代码>固定< /COD>语句中,以防止它在内存中移动。它在哪一行代码中抛出该异常?它没有说明,因此我无法找到它。然而,我对所有代码进行了注释,并一个接一个地添加函数,并意识到当我调用这个TimeSetEvent时,它将在大约20次迭代后很快崩溃。即使函数什么也不做。然而,不称之为“工作”(=不会崩溃,但显然我需要那个计时器)。timeSetEvent做什么?它就像计时器一样。计时器更精确。它被称为定时器多媒体,具有可编辑的高精度,适用于高达1ms的windows)。如果您不向我们展示一个计时器,我们将无法回答。我怀疑这个问题是由一个托管对象引起的,该对象被gc删除或移动。考虑将TimeReEvEndEnter保持在范围内,或者将其封装在<代码>固定< /COD>语句中,以防止它在内存中移动。调试器通常总是为此生成。彻底检查调试器设置可能是合适的。正确的解决方案是GCHandle.Alloc()。嘿@HansPassant,您能提供一些关于GCHandle.Alloc()的示例或更多上下文吗
TimerEventHandler
是一个委托,从我所能读到的()来看,它们不能被固定。还请注意,您不需要(实际上也不能)固定委托。但是,您需要将委托的生存期延长到可以从非托管代码调用的时间。也不确定如何检查诊断。与固定无关,您通过GCHandleType.Normal。这样GC总是看到一个对象引用而不会收集它。如果我实现的Dispose失败,将检查如何执行!调试器通常总是为此生成。彻底检查调试器设置可能是合适的。正确的解决方案是GCHandle.Alloc()。嘿@HansPassant,您能提供一些关于GCHandle.Alloc()的示例或更多上下文吗
TimerEventHandler
是一个委托,从我所能读到的()来看,它们不能被固定。还请注意,您不需要(实际上也不能)固定委托。但是,您需要将委托的生存期延长到可以从非托管代码调用的时间。也不确定如何检查诊断。与固定无关,您通过GCHandleType.Normal。这样GC总是看到一个对象引用而不会收集它。如果我实现的Dispose失败,将检查如何执行!