我已经在几个地方读过有关承诺处理器模式,但我无法弄清楚它是什么.有人建议我在代码中使用它,看起来像:
function getDb(){
return myDbDriver.getConnection();
}
var users = getDb().then(function(conn){
return conn.query("SELECT name FROM users").finally(function(users){
conn.release();
});
});
Run Code Online (Sandbox Code Playgroud)
什么是承诺处理器模式以及它如何应用于此?
注意 - 在原生承诺中,我.finally
称之为"添加拒绝和履行处理程序,返回值但执行操作".如果重要的话,我在这种情况下使用蓝鸟.
我很困惑处置.我正在尝试让我的代码正确处理资源.所以我一直在将我的类设置为IDisposable(使用Dispose方法),确保调用Dispose方法.
但是现在FXCop告诉我很多关于Disposing = false和调用Dispose(false)的东西.
我没有看到一个带有bool的Dispose方法.我需要制作一个吗?如果是这样,为什么?为什么不在处理时调用一个方法呢?
我在这里看到了一些代码:http://msdn.microsoft.com/en-us/library/ms244737.aspx,它展示了如何制作一个带有bool的Disposing方法.它表示它适用于本地和管理资源. 但我认为处理的全部内容仅适用于非管理资源.
此外,FXCop抱怨的路线是这样的:
~OwnerDrawnPanel()
{
_font.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
它说:
CA1063:Microsoft.Design:修改'OwnerDrawnPanel .~ OwnerDrawnPanel()',以便它调用Dispose(false)然后返回.
但是Font上没有Dispose(bool)(我能找到).
为什么我需要Dispose(bool)?如果我这样做,为什么Font没有呢?因为它没有它,为什么FXCop要求我使用它?
感谢所有的好答案.我想我现在明白了.这是
处置"非管理"资源分为两类:
Dispose(bool)用于表示两者之间的区别:
我今天和我的同事进行了一次对话,她说她刚刚了解了使用该using
声明背后的原因.
//Using keyword is used to clean up resources that require disposal (IDisposable interface).
using (StreamReader reader = new StreamReader(@"C:\test.txt"))
{
string line = reader.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我指出,除非GC决定这样做,否则该物体被标记为"可以处置"但实际上没有处理和垃圾收集.
她回答说,一旦using语句结束,对象将自动处理,因为using语句被转换为try-catch-finally块.因此,对象必须放在using语句的最后.
我对此感到困惑,因为我知道使用using
语句并不能保证对象被GC收集.所有发生的事情都是Dispose()
调用该方法.GC无论如何都决定GC.但当她要求证明时,我找不到任何证据.
有谁知道这是如何工作的,以及如何证明它?
以下是一位同事撰写的示例代码.这对我来说显然是错的,但我想检查一下.一个对象应该从一个自己的方法中调用自己的Dispose()方法吗?在我看来,只有对象的所有者/创建者在完成对象而不是对象本身时才应该调用Dispose().
它是一个.asmx web方法,在完成时调用Dispose().(事实上,这是一个Web方法可能是一般问题的偶然事实.)在我们的代码库中,我们有时在其他Web服务的方法中实例化Web服务类,然后调用它们上的方法.如果我的代码执行此操作来调用此方法,则该方法返回时该对象是toast,并且我无法再使用该对象.
[WebMethod]
public string MyWebMethod()
{
try
{
return doSomething();
}
catch(Exception exception)
{
return string.Empty;
}
finally
{
Dispose(true);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:找到一些相关的链接:
在Visual Studio中创建新表单时,设计器在.Designer.cs文件中生成以下代码:
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
Run Code Online (Sandbox Code Playgroud)
components
变量的目的是什么?我的理论是,我应该将它用于IDisposable
我的表单拥有的任何类,我在Designer之外创建(因为Dispose
已经由Designer实现).
因此,例如,如果我的表单拥有一个字体,我可以通过添加它来确保它被处理components
:
public partial class Form1 : Form
{
Font coolFont;
public Form1()
{
InitializeComponent();
this.coolFont = new Font("Comic …
Run Code Online (Sandbox Code Playgroud) 有时我们需要在SharePoint中执行小型管理任务.一个简单的PowerShell脚本是一个非常好的工具.例如,这样的脚本可以枚举列表的事件处理程序:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = new-object Microsoft.SharePoint.SPSite($args[0])
$site.RootWeb.Lists["MyList"].EventReceivers > C:\MyListHandlers.txt
Run Code Online (Sandbox Code Playgroud)
据了解,类似的对象SPSite
,并SPWeb
必须Dispose()
在通话后-d,否则会出现内存泄漏.最好的是打电话
$site.RootWeb.dispose()
$site.dispose()
Run Code Online (Sandbox Code Playgroud)
在这个脚本的末尾.但是如果这是一个只运行一次的Powershell脚本,并且我们知道PowerShell在执行后会清理 - 那么不调用dispose()是不是很糟糕?
所以,我的问题是 - 如果有时我运行这样的脚本,会有一些危险吗?它会影响SharePoint场(或我运行脚本的服务器)的整体稳定性吗?
我需要强制使用"使用"来处理类的新实例.
public class MyClass : IDisposable
{
...
}
using(MyClass obj = new MyClass()) // Force to use "using"
{
}
Run Code Online (Sandbox Code Playgroud) 我有一个包含大量静态成员的类,其中一些保留对托管和非托管对象的引用.
例如,一旦引用了Type,就会调用静态构造函数,这会导致我的类启动tasks的blockingQueue.例如,当调用其中一个静态方法时会发生这种情况.
我实现了IDisposable,它为我提供了处理我创建的任何实例对象的方法.但是,如果使用者不从我的类创建任何实例对象,则永远不会调用这些方法.
如何以及在何处放置代码来处理由我的类的静态部分维护的引用?我一直认为在释放最后一个实例对象时会发生静态引用资源的处理; 这是我第一次创建一个不会创建任何实例的类.
在方法中将自定义对象设置为null
(Nothing
在VB.NET中)是否有意义Dispose()
?这可以防止内存泄漏或无用吗?!
让我们考虑两个例子:
public class Foo : IDisposable
{
private Bar bar; // standard custom .NET object
public Foo(Bar bar) {
this.bar = bar;
}
public void Dispose() {
bar = null; // any sense?
}
}
public class Foo : RichTextBox
{
// this could be also: GDI+, TCP socket, SQl Connection, other "heavy" object
private Bitmap backImage;
public Foo(Bitmap backImage) {
this.backImage = backImage;
}
protected override void Dispose(bool disposing) {
if (disposing) …
Run Code Online (Sandbox Code Playgroud) 我常常发现自己编写的代码如下:
if (Session != null)
{
Session.KillAllProcesses();
Session.AllUnitsReady -= Session_AllUnitsReady;
Session.AllUnitsResultsPublished -= Session_AllUnitsResultsPublished;
Session.UnitFailed -= Session_UnitFailed;
Session.SomeUnitsFailed -= Session_SomeUnitsFailed;
Session.UnitCheckedIn -= Session_UnitCheckedIn;
UnattachListeners();
}
Run Code Online (Sandbox Code Playgroud)
目的是清理我们在目标(会话)上注册的所有事件订阅,以便GC可以自由处理会话.我与同事讨论了实现IDisposable的类,但他相信这些类应该像这样执行清理:
/// <summary>
/// Disposes the object
/// </summary>
public void Dispose()
{
SubmitRequested = null; //frees all references to the SubmitRequested Event
}
Run Code Online (Sandbox Code Playgroud)
是否有理由选择一个而不是另一个?有没有更好的方法来解决这个问题?(除了各处的弱参考事件)
我真正希望看到的是一些类似于引发事件的安全调用模式:即安全和可重复.每次我附加到活动时我都记得要做的事情,这样我就可以确保清理起来很容易.
dispose ×10
c# ×8
.net ×4
idisposable ×3
bluebird ×1
designer ×1
events ×1
javascript ×1
powershell ×1
promise ×1
sharepoint ×1
using ×1
vb.net ×1
web-services ×1
winforms ×1