我是C#的新手,我遇到了以下警告信息:
警告CA1001实施IDisposable 'form_Inspection_Upload.d__4',因为它创建 以下IDisposable类型的成员:'StringReader', 'WebServicesSoapClient'
这是使用VS Express 2015 for Desktop,Windows 7操作系统进行重建的结果。我查看了各种类似消息的帖子,但未能看到它们如何适用于下面显示的代码。上面的警告说'StringReader'对象(“a_string_reader”)需要处理?如果是这样,为什么在“USING子程序结束后”没有处理它?</ p>
在同一代码块中进一步向下是'WebServicesSoapClient'对象(“ebws”)。据我所知,它没有Dispose
方法,但可以关闭。关闭服务客户端是否与将其删除无关?显然,不,但我不确定如何在https://msdn.microsoft.com/library/ms182172.aspx上显示IDisposable
。
如果它有帮助,这里是代码。有问题的部分是倒数第三个代码块(重要部分包含注释// important line
。):
private async void button_Upload_Click(object sender, EventArgs e)
{
using (StringReader a_string_reader = new StringReader(pdf_doc_string)) // important line
{ do
{
a_line = a_string_reader.ReadLine();
} while (a_line != null);
}
eBridge.WebServicesSoapClient ebws = new eBridge.WebServicesSoapClient(); // important line
eBridge.FileUploadResponse upload_result = await ebws.FileUploadAsync(User, Password, Cabinet, b, File_Path, Index1_Program, Index2_Permit_Number, Index3_Name, Index4_Address, Index5_ZipCode, Index6_Doc_Date, Index7_Doc_Type);
ebws.Close(); // important line
}
}
答案 0 :(得分:1)
我遇到过马克·西曼的博客&#39; ploeh博客&#39;文章&#34;如何从表格中处理成员&#34; (http://blogs.msdn.com/b/ploeh/archive/2006/08/10/howtodisposemembersfromforms.aspx)以点击给我的方式解决了这个问题。谢谢你!同样非常有帮助的是Henk指出警告适用于成员。
请不要犹豫,纠正或澄清这个帖子,因为我对C#和相关术语的了解非常新手。
简短的回答是为每个需要处理的对象创建一个公共类,并将子类IDisposable添加到对象&#39;基类。在类中为对象创建Dispose方法。然后将该项目带入表单。
更详细的解释如下:
. public class eBWS : eBridge.WebServicesSoapClient, IDisposable
{
public eBWS(<arguments>)
{
this.FileUploadExAsync(<arguments>);
}
public void Dispose() { }
}
在button_Upload_Click方法中,替换了
. using (eBridge.WebServicesSoapClient ebws = new eBridge.WebServicesSoapClient())
{
eBridge.FileUploadResponse upload_result = await ebws.FileUploadAsync(<arguments>);
textBox_Results.Text = upload_result.ToString();
}
与
. ebws = new eBWS(<arguments>);
对StringReader对象使用了类似的方法,但现在遇到了另一个问题。这里不解决它。
如果博客应该从网上消失,那么完整的文字就会出现(再次,感谢Mark Seemann博客&#39; ploeh博客&#39;文章&#34;如何从表格中处理成员& #34):
2006年8月5:22 19
当您创建新表单(或UserControl)时,Visual Studio会将其创建为部分类,设计器生成的代码将进入* .Designer.cs文件。设计代码中的另一段代码是System.ComponentModel.Component.Dispose(bool)的覆盖,它包含处理表单及其包含的组件的代码。它总是这样:
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
有点不幸的是,这个方法被覆盖了,因为它使你自己的处理逻辑添加到表单更加困难,因为你不能再次在同一个类中覆盖该方法 - 请记住,您控制的表单代码只是类定义的一部分。您显然可以直接编辑设计器文件,但不建议这样做。
如果您需要在表单中执行一些额外的处置逻辑,那么您可以做什么?如果你的一个成员变量实现了IDisposable,那么这个需求很容易就会到来,在这种情况下你真的应该在Form处理时处理掉它。想象一下,你有以下IDisposable类:
public class MyDisposable : IDisposable
{
private string message_;
public MyDisposable(string message)
{
this.message_ = message;
}
#region IDisposable Members
public void Dispose()
{
MessageBox.Show(this.message_);
}
#endregion
}
您现在希望在表单中有一个MyDisposable成员变量,并且在表单处理时需要处理它:
public partial class MyForm : Form
{
private MyDisposable myDisposable_;
public MyForm()
{
InitializeComponent();
this.myDisposable_ =
new MyDisposable("Goodbye, World");
}
}
当您运行应用程序并关闭表单时,表单正在处理,但您从未看到再见消息,因为myDisposable_未被处理。设计器代码中的Dispose方法处理表单的dispose逻辑,它对myDisposable_成员变量一无所知。
然而,它确实处理了它的组件成员,并且由于这是一个IContainer,如果你可以将myDisposable_添加到容器中,问题就解决了。不幸的是,IContainer只接受IComponent实例,如果您不想在MyDisposable上实现IComponent。
IComponent合同的一部分是实现必须有一个默认构造函数,并且出于API设计原因,您可能找不到可接受的IDisposable类型 - 出于某种原因,我不认为&#39 ;对于MyDisposable来说,这是一个可接受的变化。
但是,您可以做的是将这个小类的实例添加到容器中:
internal class Disposer : Component
{
private Action<bool> dispose_;
internal Disposer(Action<bool> disposeCallback)
{
this.dispose_ = disposeCallback;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
this.dispose_(disposing);
}
}
从表单代码中,您需要将一个新的Disposer实例与一个包含真实配置逻辑的委托连接起来。在MyForm中使用时,它现在看起来像这样:
public partial class MyForm : Form
{
private MyDisposable myDisposable_;
public MyForm()
{
InitializeComponent();
this.myDisposable_ =
new MyDisposable("Goodbye, World");
this.components.Add(new Disposer(this.OnDispose));
}
private void OnDispose(bool disposing)
{
this.myDisposable_.Dispose();
}
}
请注意,我添加了一个新的Disposer实例,该实例指向新的OnDispose方法,然后该方法实现了设计器代码未处理的所有dispose逻辑。现在,当我运行应用程序并关闭Form时,我得到了预期的MessageBox。
这种技术通常可以在需要处理成员变量时使用,但由于设计器代码已经覆盖了Dispose方法,因此无法使用。但是,如果您的成员变量也没有实现IComponent,我只推荐这种方法。
如果您可以控制成员变量的类并且不介意使用默认构造函数,我建议您改为实现IComponent(最简单的方法是从System.ComponentModel派生) .Component就像我使用Disposer类一样)。这通常会为您提供更好的设计时体验,因为您现在可以将组件从工具箱拖到设计图面,设计器(Visual Studio)会自动将其添加到组件成员变量中,因此它将是与容器中的所有其他组件一起放置。
如果您正在创建UserControl,这两种方法也都有效,尽管如此,您可能需要自己实例化组件成员变量。