`
happmaoo
  • 浏览: 4472280 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[AsyncHandle]什么引发了ObjectDisposedException?

阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

[AsyncHandle]什么引发了ObjectDisposedException

Version

Date

Creator

Description

<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False"><span lang="EN-US" style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">1.0.0</span></chsdate>.1

<chsdate w:st="on" year="2006" month="9" day="19" islunardate="False" isrocdate="False"><span lang="EN-US" style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">2006-9-19</span></chsdate>

郑昀

草稿

继续阅读之前,我们假设您熟悉以下知识:

n IDisposable接口释放dotNET资源

如果不熟悉这些知识点,可以看本文最后资源列表中的文章。

本文讨论了出现不可捕获的ObjectDisposedException异常崩溃,寻找可能的原因,并试图解决。

[现象]

关键词 ObjectDisposedException

表象 我的dotNET C#服务偶尔会彻底崩溃,时机没有规律可循,崩溃时在Windows事件日志中有来自于“.NET Runtime 2.0 Error Reporting”的报告,描述的错误也颇让人费思量。

错误描述

事件类型: 错误

事件来源: .NET Runtime 2.0 Error Reporting

事件种类:

事件 ID: 5000

描述:

EventType clr20r3, P1 juiceextractor.exe, P2 <chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.0.0</chsdate>.0, P3 450d5160, P4 mscorlib, P5 2.0.0.0, P6 4333ab80, P7 10ed, P8 0, P9 system.objectdisposedexception, P10 NIL.

通过ObjectDisposedException对我们的提醒,可以了解到这是因为前面已经使用了一个disposed对象。在一个使用过disposed对象上调用其他方法时是会引发致命异常的,服务也不知道该在哪里捕获这个异常,似乎也不可捕获。但是,问题是,是谁引发的?

引申 看到微软的一个对dotnet frameworkservicepack公告中提到:当一个异步Web 请求在接收到响应之前如果被中止,则会引发ObjectDisposedException

唯一和异步请求有点关系的是,本服务向一个socket服务器发送请求,并等候一段一段地循环接收服务器的大量数据反馈。这中间,使用了C#的异步方法BeginReceive来告知socket如何接收数据。

这个逻辑的代码如下:

C# code

/// <summary><p></p></summary>

/// 调用异步方法BeginReceive来告知socket如何接收数据

///

IAsyncResult ar =

_socket.BeginReceive(_recvBuffer.Buffer, 0, _recvBuffer.Buffer.Length,

SocketFlags.None, _recvCallback, _socket);

// 设定一个期限,10分钟内如果还没有结果返回,

// 我们可以认为必须关掉当前socket连接了,不要再等了!

ar.AsyncWaitHandle.WaitOne(new TimeSpan(0, 10, 0), true);

ar.AsyncWaitHandle.Close();

….

public void RecvCallback(IAsyncResult result)

{…

也就是利用回调函数 _recvCallback”,每次有数据的话,都直接调用它。但是,规定了如果10分钟内都没有完整结果返回,那么这个异步等候句柄将被关闭。

很简单的想法。

但是如果数据量大的话,socket服务器计算的过程非常漫长,导致返回数据的过程超过了10分钟,会发生什么事情呢?

[回答前面的问题]

这个时候,“ar.AsyncWaitHandle.Close();”是不是就导致了ObjectDisposedException呢?

假设如此的话。

第一,那我们需要调用AsyncWaitHandle.Close()这句话吗?

The Thread Pool and Asynchronous Methods中说道:“Note the call to ar.AsyncWaitHandle.Close(). This prevents the WaitHandle leaking until garbage collection. The leak wouldn't cause any problems in most cases (unlike, for instance, file handles leaking), but in situations where FireAndForget would be called many, many times in quick succession, you could end up with a vast number of handles until the garbage collector started finalizing them. (This is also a bad thing in terms of performance - you shouldn't leave things to be finalised when it can be avoided.)

那么,也许我们可以不调用它,来规避ObjectDisposedException异常崩溃?

第二,把ar.AsyncWaitHandle.WaitOne(new TimeSpan(0, 10, 0), true);等候的时间延长?比如说延长到40分钟。这样也可以避免ObjectDisposedException

[改变接收模式]

第三,对于这种长时间执行的socket服务器,可以不用在一个端口上干等,可以发送请求用一个端口,接收数据反馈用另外一个socket端口号。

以前没有考虑到计算时间如此之长,所以才做成了socket异步接收模式。后来算法作了改变,有时候十分钟的等候都不够了。

[参考资料]

IDisposable接口释放.NET资源

The Thread Pool and Asynchronous Methods




分享到:
评论

相关推荐

    c#教程 深入浅出第十章

    `using`语句可用于资源管理,确保在完成使用后正确关闭或释放资源,避免引发`ObjectDisposedException`等异常。 调试是处理异常的关键工具。IDE如Visual Studio提供的调试器允许你暂停程序执行,逐行检查代码,查看...

    dotnet 使用 NamedPipeClientStream 连接一个不存在管道服务名将不断空跑 CPU 资源.rar

    这个问题在实际开发中需要注意,避免引发性能问题。本文档将深入探讨此问题,并提供解决方案。 首先,我们来理解一下NamedPipeClientStream的工作原理。当创建一个NamedPipeClientStream实例并调用`Connect()`方法...

    C#高级编程 错误和异常

    如果对象已经被释放,`Open()`方法会抛出`ObjectDisposedException`,这是一个预定义的异常类型,表明对象不再可用。在读取文件第一行后,如果解析过程失败,会抛出自定义的`ColdCallFileFormatException`,并携带...

    C#任务管理器 进程管理器

    首先,我们要明确什么是进程。在操作系统中,进程是程序执行的实例,每个进程都有独立的内存空间和系统资源。在C#中,`System.Diagnostics`命名空间下的`Process`类是进行进程管理的主要工具。 1. **查看进程**: ...

    c#命名管道发送接收消息实例

    首先,我们要理解什么是命名管道。命名管道是Windows操作系统提供的一个高级通信机制,它允许在同一台计算机上的不同进程之间进行双向通信。相比于其他IPC方式,如内存映射文件或套接字,命名管道通常具有较低的开销...

    PDA蓝牙通信的程序(C#)

    此外,为了提高程序的健壮性,可以添加异常处理机制,对可能出现的IOException、ObjectDisposedException等异常进行捕获和处理。 在“BlueTooth(RS232)”这个文件中,很可能包含了实现以上逻辑的源代码示例。通过...

    C#开发HID工具的接口

    因此,需要在代码中适当地捕获和处理异常,例如`IOException`、`ObjectDisposedException`等。 6. **创建HID工具:** 使用上述接口,开发者可以构建自定义的HID调试工具。工具可能包括设备选择界面、数据发送和...

    在多线程中如何调用Winform.pdf

    在多线程环境中操作Winform控件时,如果不遵循这些规则,可能会导致`InvalidCastException`、`InvalidOperationException`或`ObjectDisposedException`等异常。因此,确保跨线程调用的代码的健壮性对于开发稳定的...

    TCPIP异步读取.rar

    异步操作可能会抛出异常,如`IOException`、`ObjectDisposedException`等。因此,回调函数中应包含适当的异常处理代码,确保程序的健壮性。 4. **性能优化**: - 使用缓冲池管理字节数组,减少内存分配和释放的...

    浅析C# 使用Process调用外部程序中所遇到的参数问题

    例如,如果`UseShellExecute`属性设为`true`,那么`Process.Start`将使用操作系统的外壳程序来启动进程,这可能引发安全风险。同时,确保在适当的时候关闭`Process`对象,避免资源泄露。 总之,`Process.Start`是C#...

    stream 通讯

    在使用Stream进行数据传输时,需要注意异常处理,如IOException、ObjectDisposedException等,确保在异常发生时能正确地关闭流并释放资源。 七、Stream的使用最佳实践 1. 使用using语句块自动管理Stream对象的生命...

    socket用法

    常见的异常包括`SocketException`(网络相关的错误)、`ArgumentNullException`(参数为空)和`ObjectDisposedException`(对象已被释放)。处理这些异常可以确保程序的健壮性和用户友好的体验。 ```csharp try { ...

    C# 编写服务器端接收文件

    - `ObjectDisposedException`:当Socket已被关闭后仍尝试使用时抛出。 确保正确处理这些异常对于维护程序的稳定性和安全性至关重要。 #### IPHostEntry类解析 `IPHostEntry`类存储了Internet主机的详细信息,包括...

    TcpClient 异步读取数据

    catch (ObjectDisposedException) // 如果连接已关闭,忽略 { } catch (Exception ex) { // 连接可能已断开,处理异常 HandleConnectionLost(ex); } } private void SendHeartbeat() { // 创建心跳包数据 ...

    C#网络编程概述

    需要注意的是,使用这些方法时可能会遇到SocketException、ArgumentNullException和ObjectDisposedException等异常。 2. **IPHostEntry类**:IPHostEntry对象存储了关于Internet主机的地址信息,包括AddressList...

    c#中的非托管资源释放 (Finalize和Dispose)

    - 当`Dispose`方法完成后,如果再次调用`Dispose`方法或尝试访问已释放的资源,则应抛出`ObjectDisposedException`异常。 3. 在实现`Dispose`方法时,还需要注意: - 可以通过检查一个布尔标志变量来确定是否...

    C # 语言网络编程概述

    - `ObjectDisposedException`:如果 Socket 已经关闭。 **示例代码**: ```csharp IPHostEntry host = Dns.GetHostEntry("www.example.com"); IPAddress ipAddress = (IPAddress)host.AddressList[0]; ``` ##### ...

Global site tag (gtag.js) - Google Analytics