我通常在表单上有这样的代码:
private void PerformLongRunningOperation()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate
{
// perform long running operation here
};
worker.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
这意味着我不会处理它BackgroundWorker
,而如果我已经由表单设计者添加它,那么我认为它会被处理掉.
这会导致任何问题吗?声明模块级别_saveWorker
,然后Dispose
从表单的dispose方法调用它更正确吗?
关闭后我还应该打电话Dispose()
给我的插座吗?
例如:
mySocket.Shutdown(SocketShutdown.Both);
mySocket.Close();
mySocket.Dispose(); // Redundant?
Run Code Online (Sandbox Code Playgroud)
我想知道因为MSDN文档说明如下:
关闭Socket连接并释放所有相关资源.
我是C#的新手,如果这是一个明显的问题,请道歉.
在MSDN Dispose示例中,它们定义的Dispose方法是非虚拟的.这是为什么?这对我来说似乎很奇怪 - 我希望IDisposable的子类具有自己的非托管资源,它只会覆盖Dispose并在自己的方法底部调用base.Dispose().
谢谢!
我有List对象.我该如何处理清单?
例如,
List<User> usersCollection =new List<User>();
User user1 = new User();
User user2 = new User()
userCollection.Add(user1);
userCollection.Add(user2);
Run Code Online (Sandbox Code Playgroud)
如果我确定userCollection = null;
会发生什么?
foreach(User user in userCollection)
{
user = null;
}
Run Code Online (Sandbox Code Playgroud)
哪一个最好?
我需要一些关于该Dispose
方法实现的建议.
在我们的应用程序中,用户设计自己的UI.我有一个预览窗口,显示UI的外观.此UI中绘制的所有对象最终都来自公共基类ScreenObject.我的预览管理器包含对ScreenGrid的单个对象引用,ScreenGrid是整个预览区域的网格对象.
问题#1
我的一些派生屏幕类保留了非托管资源,例如数据库连接,位图图像和WebBrowser
控件.这些类需要处理这些对象.我在基类中创建了一个虚Dispose
方法,ScreenObject
然后Dispose
在每个派生类中实现了一个覆盖非托管资源的覆盖方法.但是,现在我刚刚创建了一个名为的方法Dispose
,我没有实现IDisposable
.我应该实施IDisposable
吗?如果是这样,我该如何实现它?
将虚Dispose
方法放在没有非托管资源的基类中是否错误,以便您可以利用多态?
问题2
在阅读有关Dispose
方法和IDisposable
接口的过程中,Microsoft声明处置对象应该只调用Dispose
其父对象的方法.父母将为其父母调用它,依此类推.对我而言,这似乎是倒退.我可能想要处理一个孩子但保留其父母.
我认为它应该是另一种方式,处置的对象应该处理它的孩子.然后孩子们应该处理他们的孩子等等.
我错在这里还是我错过了什么?
我显然已经习惯了一个糟糕的编码习惯.这是我写的代码示例:
using(StreamReader sr = new StreamReader(File.Open("somefile.txt", FileMode.Open)))
{
//read file
}
File.Move("somefile.txt", "somefile.bak"); //can't move, get exception that I the file is open
Run Code Online (Sandbox Code Playgroud)
我认为,因为using
条款明确要求Close()
,并Dispose()
在StreamReader
该FileStream
会也关闭.
我能解决问题的唯一方法是将上面的块更改为:
using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
{
using(StreamReader sr = new StreamReader(fs))
{
//read file
}
}
File.Move("somefile.txt", "somefile.bak"); // can move file with no errors
Run Code Online (Sandbox Code Playgroud)
应该StreamReader
通过在第一个区块中关闭而关闭底层FileStream
?或者,我错了吗?
我决定发布实际的违规代码块,看看我们是否可以深入了解这一点.我现在很好奇.
我以为我在using
条款中遇到了问题,所以我把所有内容都扩展了,每次都无法复制.我在这个方法调用中创建了文件,所以我认为其他任何文件都没有打开句柄.我还验证了Path.Combine
调用返回的字符串是否正确.
private static void GenerateFiles(List<Credit> credits)
{
Account i; …
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
namespace DisposeTest
{
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Calling Test");
Test();
Console.WriteLine("Call to Test done");
}
static void Test()
{
DisposeImplementation di = new DisposeImplementation();
}
}
internal class DisposeImplementation : IDisposable
{
~DisposeImplementation()
{
Console.WriteLine("~ in DisposeImplementation instance called");
}
public void Dispose()
{
Console.WriteLine("Dispose in DisposeImplementation instance called");
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使我在Test();
调用之后放置了一个等待循环,Dispose也永远不会被调用.所以这很糟糕.我想编写一个简单易用的类,以确保清理所有可能的资源.我不想把这个责任交给我班级的用户.
可能的解决方案:使用using
或调用自己处理(基本相同).我可以强制用户使用吗?或者我可以强制调用处理吗?
呼叫GC.Collect();
后Test();
也不起作用.
把di
以null
不调用任何处置.解构器可以工作,因此对象在退出时会被解构Test()
好的,现在很清楚!
谢谢大家的答案!我会在评论中添加警告!
如果我有一个SomeDisposableObject
实现的类IDisposable
:
class SomeDisposableObject : IDisposable
{
public void Dispose()
{
// Do some important disposal work.
}
}
Run Code Online (Sandbox Code Playgroud)
我有另一个叫做的类AContainer
,它有SomeDisposableObject
一个公共属性的实例:
class AContainer
{
SomeDisposableObject m_someObject = new SomeDisposableObject();
public SomeDisposableObject SomeObject
{
get { return m_someObject; }
set { m_someObject = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后FxCop将坚持AContainer
也是IDisposable
.
这是很好的,但我看不出我可以安全地调用m_someObject.Dispose()
从AContainer.Dispose()
,作为另一个类可能还是要在一个参考m_someObject
实例.
避免这种情况的最佳方法是什么?
(假设其他代码依赖于AContainer.SomeObject
始终具有非空值,因此只是将实例的创建移到外部AContainer
不是一个选项)
编辑:我将扩展一些例子,因为我认为一些评论者错过了这个问题.如果我只实现一个调用m_someObject.Dispose()的Dispose()
方法,AContainer
那么我将留下这些情况:
// Example One
AContainer …
Run Code Online (Sandbox Code Playgroud) 我的工作线程中有以下代码(ImageListView
下面是派生自的Control
):
if (mImageListView != null &&
mImageListView.IsHandleCreated &&
!mImageListView.IsDisposed)
{
if (mImageListView.InvokeRequired)
mImageListView.Invoke(
new RefreshDelegateInternal(mImageListView.RefreshInternal));
else
mImageListView.RefreshInternal();
}
Run Code Online (Sandbox Code Playgroud)
但是,我ObjectDisposedException
有时会得到Invoke
上面的方法.似乎控制可以在我检查IsDisposed
和呼叫之间处理Invoke
.我怎么能避免这种情况?
我正在使用StructureMap来解析对我的存储库类的引用.我的存储库接口实现了IDisposable,例如
public interface IMyRepository : IDisposable
{
SomeClass GetById(int id);
}
Run Code Online (Sandbox Code Playgroud)
使用Entity Framework实现接口:
public MyRepository : IMyRepository
{
private MyDbContext _dbContext;
public MyDbContext()
{
_dbContext = new MyDbContext();
}
public SomeClass GetById(int id)
{
var query = from x in _dbContext
where x.Id = id
select x;
return x.FirstOrDefault();
}
public void Dispose()
{
_dbContext.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
无论如何提到我正在使用StructureMap来解析IMyRepository.那么何时,何地以及如何调用我的处理方法?
dispose ×10
c# ×9
.net ×3
idisposable ×3
asp.net ×1
controls ×1
filestream ×1
invoke ×1
list ×1
sockets ×1
streamreader ×1
structuremap ×1