在实现IDisposable时,我认为在对象被处理后不应该调用的每个方法都应该抛出ObjectDisposedException.但是应该传递给异常构造函数的name对象的标准是什么?
我创建了一个MemoryStream,传递给CryptoStream写作.我希望CryptoStream加密,然后让MemoryStream我开放,然后阅读其他内容.但是一旦CryptoStream被处置,它MemoryStream也会被处置掉.
可以以某种方式打开CryptoStream基地MemoryStream吗?
using (MemoryStream scratch = new MemoryStream())
{
using (AesManaged aes = new AesManaged())
{
// <snip>
// Set some aes parameters, including Key, IV, etc.
// </snip>
ICryptoTransform encryptor = aes.CreateEncryptor();
using (CryptoStream myCryptoStream = new CryptoStream(scratch, encryptor, CryptoStreamMode.Write))
{
myCryptoStream.Write(someByteArray, 0, someByteArray.Length);
}
}
// Here, I'm still within the MemoryStream block, so I expect
// MemoryStream to still be usable. …Run Code Online (Sandbox Code Playgroud) 我使用以下代码:
private WSHttpBinding ws;
private EndpointAddress Srv_Login_EndPoint;
private ChannelFactory<Srv_Login.Srv_ILogin> Srv_LoginChannelFactory;
private Srv_Login.Srv_ILogin LoginService;
Run Code Online (Sandbox Code Playgroud)
Login是我的构造函数:
public Login()
{
InitializeComponent();
ws = new WSHttpBinding();
Srv_Login_EndPoint = new EndpointAddress("http://localhost:2687/Srv_Login.svc");
Srv_LoginChannelFactory = new ChannelFactory<Srv_Login.Srv_ILogin>(ws, Srv_Login_EndPoint);
}
Run Code Online (Sandbox Code Playgroud)
我正在以这种方式使用服务:
private void btnEnter_Click(object sender, EventArgs e)
{
try
{
LoginService = Srv_LoginChannelFactory.CreateChannel();
Srv_Login.LoginResult res = new Srv_Login.LoginResult();
res = LoginService.IsAuthenticated(txtUserName.Text.Trim(), txtPassword.Text.Trim());
if (res.Status == true)
{
int Id = int.Parse(res.Result.ToString());
}
else
{
lblMessage.Text = "Not Enter";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{ …Run Code Online (Sandbox Code Playgroud) 我正在构建一个4层ASP.Net Web应用程序.这些图层是:
实体层具有我的数据模型类,并使用T4模板(POCO)从数据层中的实体数据模型(edmx文件)构建.实体层在所有其他层中引用.
我的数据层有一个名为SourceKeyRepository的类,它具有如下函数:
public IEnumerable<SourceKey> Get(SourceKey sk)
{
using (dmc = new DataModelContainer())
{
var query = from SourceKey in dmc.SourceKeys
select SourceKey;
if (sk.sourceKey1 != null)
{
query = from SourceKey in query
where SourceKey.sourceKey1 == sk.sourceKey1
select SourceKey;
}
return query;
}
}
Run Code Online (Sandbox Code Playgroud)
由于我不希望我的查询在此应用程序的其他层中运行,因此禁用了延迟加载.尝试访问UI层中的信息时,我收到以下错误:
ObjectContext实例已被释放,不能再用于需要连接的操作.
我确定这是因为我的DataModelContainer"dmc"被处理掉了.如何从我的数据层返回此IEnumerable对象,以便它不依赖于ObjectContext,而只依赖于DataModel?
有没有办法限制延迟加载只发生在数据层?
我的游戏窗口允许手动调整大小,这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小.游戏还使用RenderTarget2D rt2d了主渲染目标在主Draw方法中设置的a:,GraphicsDevice.SetRenderTarget(rt2d)但它null在主Draw方法的末尾被重置回(默认渲染目标),这使得它有点令人困惑:这是否真的是问题的根源,在Render Target设置为的时刻之前调整游戏窗口的大小rt2d,而不是重置为默认值?现在它看起来像.
主Draw方法中的代码应该始终将主渲染目标重置为null,因此没有预期的情况,这通常不会发生.
尽管如此,调整游戏窗口大小的结果有时会导致GraphicsDevice.isDisposed返回true,然后游戏会System.ObjectDisposedException在第一个时间内抛出SpriteBatch.End().我发现有关这个错误的帖子可以追溯到XNA的第一天,但是没有一个很好的解释(也没有提到改变渲染目标,所以它也可能是这些海报问题的根源).
现在,我可以通过调用此方法几次来触发此错误:
graphics.PreferredBackBufferWidth = graphics.PreferredBackBufferWidth;
graphics.PreferredBackBufferHeight = graphics.PreferredBackBufferHeight;
graphics.ApplyChanges();
Run Code Online (Sandbox Code Playgroud)
...在Draw主方法中使用以下行:
RenderTarget2D rt2d = new RenderTarget2D(GraphicsDevice,
graphics.PreferredBackBufferWidth,
graphics.PreferredBackBufferHeight);
GraphicsDevice.SetRenderTarget(rt2d);
sb.Begin();
// main draw method here, it's pretty big, so it might be taking long
// enough to process to actually resize before resetting render target
sb.End();
GraphicsDevice.SetRenderTarget(null);
sb.Begin();
// draw the whole rt2d to the screen
sb.End();
Run Code Online (Sandbox Code Playgroud)
我的猜测是,如果在重置渲染目标之前调整大小,我应该中止帧绘制并重置渲染目标,但我仍然不确定这究竟是导致这种情况的原因.
UPD …
我使用.NET 4 SerialPort对象与连接到COM1的设备进行通信.
当我完成设备后,我在SerialPort上调用Close.我不会调用Dispose,但我相信Close和Dispose在这里是同义词.
通常这很好用.
但是,有时我会在一段时间后得到以下异常(我看到的时间范围从5毫秒到175毫秒):
System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
我的代码都没有在这个堆栈上.
我找到了http://blog.zachsaw.com/2010/07/serialport-ioexception-workaround-in-c.html,但那里的解决方案没有用.在进一步检查时,问题是IOException,而不是ObjectDisposedException.
关于拔掉USB转串口设备但是COM1在板载时观察到的问题有很多帖子,所以它并没有意外消失.
这里的问题也不是我的问题; SerialPort在其使用期间保持活动状态,并且仅在我与设备通话时才关闭.(一旦我完成,设备处于不会传输任何其他数据的状态.)
SLaks 建议在入口处设置一个断点SafeHandle.Dispose,以确定我何时处理我不应该做的事情,但是我会破坏该断点数十次.SerialPort.Close当我完成使用串行设备时,我的单次调用会调用三次,其余大约一半都在GC线程中.其余部分似乎与WPF UI元素相关.
我现在不知所措.我从哪里开始?
有没有办法确定哪个SafeHandle属于哪个对象,所以我可以肯定我没有意外地处理它?
除了Close之外还有一些咒语我需要正确关闭SerialPort吗?
我有一个C#windows窗体应用程序,它通过COM端口与USB加密狗通信.我正在使用.Net 2.0中的SerialPort类进行通信,并且串行端口对象在应用程序的生命周期内是打开的.应用程序向设备发送命令,还可以从设备接收未经请求的数据.
关闭窗体时出现问题 - 在尝试关闭COM端口时,我(随机地,不幸地)得到ObjectDisposedException.这是Windows堆栈跟踪:
System.ObjectDisposedException was unhandled
Message=Safe handle has been closed
Source=System
ObjectName=""
StackTrace:
at Microsoft.Win32.UnsafeNativeMethods.SetCommMask(SafeFileHandle hFile, Int32 dwEvtMask)
at System.IO.Ports.SerialStream.Dispose(Boolean disposing)
at System.IO.Ports.SerialStream.Finalize()
InnerException:
Run Code Online (Sandbox Code Playgroud)
我找到了有类似问题的人的帖子,并尝试了解决方法[这里] [1]
[1]:http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html虽然这是针对IOException并没有阻止问题.
我的Close()代码如下:
public void Close()
{
try
{
Console.WriteLine("******ComPort.Close - baseStream.Close*******");
baseStream.Close();
}
catch (Exception ex)
{
Console.WriteLine("******ComPort.Close baseStream.Close raised exception: " + ex + "*******");
}
try
{
_onDataReceived = null;
Console.WriteLine("******ComPort.Close - _serialPort.Close*******");
_serialPort.Close();
}
catch (Exception ex)
{
Console.WriteLine("******ComPort.Close - _serialPort.Close raised exception: " + ex …Run Code Online (Sandbox Code Playgroud) 我的程序遇到了一个奇怪的问题.我正在开发一个Windows窗体应用程序.当我通过Visual Studio(F5)进行调试时,它可以正常工作,但是当我运行它的可执行文件时它会崩溃并给我"mscorlib.dll中发生了'System.ObjectDisposedException'类型的未处理异常".
我尝试将顶级(在我的最外层函数上)try/catch用于捕获此异常,但程序仍然崩溃.我在这里错过了什么?
我没有上传代码,因为我必须上传整个代码,以便查看问题所在.
我最近遇到一个错误"ObjectDisposedException:无法访问已关闭的流"
[ObjectDisposedException: Cannot access a closed Stream.]
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +10184402
System.Security.Cryptography.CryptoStream.FlushFinalBlock() +114
System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) +48
Run Code Online (Sandbox Code Playgroud)
使用以下格式的代码时:
using (var stream = new MemoryStream())
{
using (var hashStream = new CryptoStream(stream,
new SHA256Managed(), CryptoStreamMode.Write))
using (var writer = new TextWriter(hashStream))
{
writer.Write("something");
}
// ^-- Exception occurs on hashStream Dispose
// While naively I assumed that TextWriter.Dispose wouldn't touch the
// underlying stream(s).
return stream.ToArray();
}
Run Code Online (Sandbox Code Playgroud)
因此引发异常是因为TextWriter的Dispose释放了包装的Stream(hashStream).我的问题是这样的:
是否将此约定(使用默认构造函数/参数)应用于.NET中的所有流?
是否有佳能讨论这种资源使用模式?例如,可以假设CryptoStream会关闭MemoryStream吗?我知道答案,并且还有其他问题,但如果有这样的话,我希望它在设计指南方面得到解决.
这种行为记录在哪里?
我有一种非常奇怪的行为,似乎只在一种形式上发生.
基本上我正在创建一个实例Form,并调用Show()以显示非阻塞形式.在那个表单的Load事件处理程序中,我有一些可以this.Close()在某些情况下调用的逻辑.这会关闭表单,但是Show()客户端代码中的表单方法会抛出一个ObjectDisposedException.
ObjectDisposedException的堆栈跟踪如下:
在System.Windows.Forms.Control.CreateHandle()
在System.Windows.Forms.Form.CreateHandle()
在System.Windows.Forms.Control.get_Handle()
在System.Windows.Forms.ContainerControl.FocusActiveControlInternal()
在系统.Windows.Forms.Form.SetVisibleCore(布尔值)
在System.Windows.Forms.Control.Show()
...等.
这就是我所看到的:
Control.Show() 叫做OnFormLoad方法被调用FormLoad事件处理程序被调用,这里面我打电话this.Close()OnFormClosing方法被调用FormClosing事件处理程序被调用Dispose 在我的表单和所有用户控件上调用然后在Control.Show()方法结束的某个地方,它会尝试获取表单的句柄,这会因为对象被标记为处置而变形并抛出异常.
我真正的问题是,为什么我可以在没有例外的其他形式上完成同样的事情?这是GC问题吗?我尝试过GC.Collect()之后立即拨打电话this.Close()并没有任何区别.就像我说的那样,无论子用户控件,表单变量的范围等等,它都会在此表单上100%的时间内发生,而且绝不会在其他任何地方发生.
有任何想法吗?
c# ×8
.net ×4
serial-port ×2
stream ×2
winforms ×2
.net-2.0 ×1
.net-4.0 ×1
crash ×1
idisposable ×1
lazy-loading ×1
wcf ×1
xna ×1