标签: using-statement

C#网络编程和资源使用

我一直在研究如何最好地用C#编写"正确"的网络代码.

我已经看过使用C#的"using"语句的一些例子,我认为这是一个很好的方法,但是我已经看到它与各种表达式的不一致使用.

例如,假设我有一些这样的代码:

TcpClient tcpClient = new TcpClient("url.com", 80);
NetworkStream tcpStream = tcpClient.GetStream();
StreamReader tcpReader = new StreamReader(tcpStream);
StreamWriter tcpWriter = new StreamWriter(tcpStream);
Run Code Online (Sandbox Code Playgroud)

显然,这段代码非常不稳定.所以,我已经看到一些代码将使用放在tcpClient上,这似乎很好.但是,NetworkStream是否还有需要清理的资源?那么StreamReader/Writer呢?

我是否需要在嵌套的using语句中包装所有4个语句?

如果是这样,当处理时间时会发生什么?StreamWriter不会关闭流并因此关闭套接字吗?然后当StreamReader,然后是NetworkStream,然后TcpClient各自经过他们的处理时会发生什么?

这提出了另一个问题.StreamReader和StreamWriter都由同一个流组成,谁拥有它?难道他们都不认为他们拥有它,因此都会试图摧毁它吗?或者框架是否知道流已经被破坏并且只是默默地忽略它?

看起来似乎只对链中的最后一个语句使用using语句,但是如果在GetStream()中抛出异常会发生什么?我不认为它会正确清理套接字,所以似乎多余的使用是必要的,以确保不会发生这种情况.

有没有人知道有关.net网络编程的最新书籍,最好是包含异常处理和资源管理章节的c#?或者也许网上有好文章?我能找到的所有书籍都来自.NET 1.1时代(Microsoft .NET Framework的网络编程,.NET中的网络编程等),所以这看起来像是一个需要一些好资源的话题.

编辑:

请不要让Marc的评论很好地阻止其他人评论这个:)

我想听听任何人对资源管理的建议或意见,特别是有关异步使用的建议或意见.

.net c# network-programming using-statement

7
推荐指数
1
解决办法
1905
查看次数

我怎么知道使用'使用'的最佳地点?

我对c#有点新手,更习惯脚本语言.我喜欢'使用'的想法,你实例化一个对象,然后只要你需要它就在它的范围内运行,然后当它完成它的目的时你让它自己处理掉.

但是,这对我来说并不自然.当人们向我展示使用它的例子时,我认为它是一个很好的工具,但在我自己的编程中解决它的问题从来没有发生过.

如何识别好的地方using以及如何将它与try-catch块结合使用.它们是否进入块内,或者您是否通常想在try块中包含using语句?

c# using-statement

7
推荐指数
2
解决办法
449
查看次数

在using语句中声明2个类型会产生编译错误吗?

我想使用这行代码:

using (ADataContext _dc = new ADataContext(ConnectionString), BDataContext _dc2 = new BrDataContext(ConnectionString)){ // ...}
Run Code Online (Sandbox Code Playgroud)

这给出了编译错误:

不能在for,using,fixed或declartion语句中使用多个类型.

我觉得这可能吗?MSDN说它是:http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx 在MSDN示例代码中使用了Font,它是类,因此也是引用类型以及我的两个DataContext类.

这里出了什么问题?我的尝试与MSDN示例有何不同?

c# using-statement

7
推荐指数
3
解决办法
3760
查看次数

关于C#"使用"语句的样式/可读性问题

我想知道你对我所涉及的编码风格问题的看法.我意识到可能没有明确的答案,但我想看看在一个方向或另一个方向是否有强烈的偏好.

我正在通过一个解决方案using在很多地方添加语句.我常常会遇到这样的事情:

{
    log = new log();
    log.SomeProperty = something;  // several of these
    log.Connection = new OracleConnection("...");
    log.InsertData(); // this is where log.Connection will be used
    ... // do other stuff with log, but connection won't be used again
}
Run Code Online (Sandbox Code Playgroud)

其中log.Connection是OracleConnection,它实现了IDisposable.

在我的neatnik想要改变它:

{
    using (OracleConnection connection = new OracleConnection("..."))
    {
        log = new log();
        log.SomeProperty = something;
        log.Connection = conn;
        log.InsertData();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,简洁的爱好者和稍微快速完成工作的人希望这样做:

{
    log = new log();
    log.SomeProperty = something; 
    using (log.Connection = new …
Run Code Online (Sandbox Code Playgroud)

c# coding-style using-statement

7
推荐指数
2
解决办法
308
查看次数

在IDisposable对象上使用语句 - 调用Dispose方法的延迟

正如本文所述,关于在IDisposable对象上使用的用法,它说了一个有趣的词:

...使用块,在块结束后的某个时间自动调用Dispose方法.(它可能不是立即的;它取决于CLR.)

有趣的是" 它可能不是立即的;它取决于CLR ".任何人都可以提供更多细节吗?因为我们有一些奇怪的情况下,似乎在代码中使用(新MyDisposable()){...},块结束}后它立即呼吁MyDisposable例如Dispose方法,但一段时间后.

更新:结论对我来说,在我看来,我在其他地方有问题.我认为可以在使用块结束后的某个时间调用Dispose方法.但是当它不是那样的时候,我必须在我的代码中的其他地方找到问题.谢谢你的回复!

c# idisposable using-statement

7
推荐指数
2
解决办法
2755
查看次数

C#'使用'声明问题

如果使用using子句来处置连接,那么实现IDisposable的子句中的其他项是否也会自动处理?如果没有,您如何处理确保所有IDisposable项目自动处理?

public static DataTable ReturnDataTable(
    string ConnectionString, string CommandTextString, CommandType CommandType, 
    int CommandTimeout, List<System.Data.SqlClient.SqlParameter> ParameterList = null)
{
    using (System.Data.SqlClient.SqlConnection Connection =
        new System.Data.SqlClient.SqlConnection())
    {
        Connection.ConnectionString = ConnectionString;

        System.Data.SqlClient.SqlCommand Command =
            new System.Data.SqlClient.SqlCommand();
        Command.Connection = Connection;
        Command.CommandText = CommandTextString;
        Command.CommandType = CommandType;
        Command.CommandTimeout = CommandTimeout;

        if (ParameterList != null)
        {
            if (ParameterList.Count > 0)
            {
                foreach (SqlParameter parameter in ParameterList)
                {
                    Command.Parameters.AddWithValue(
                        parameter.ParameterName, parameter.Value);
                }
            }
        }

        System.Data.DataTable DataTable = new System.Data.DataTable();

        System.Data.SqlClient.SqlDataAdapter DataAdapter =
            new System.Data.SqlClient.SqlDataAdapter();
        DataAdapter.SelectCommand = Command; …
Run Code Online (Sandbox Code Playgroud)

c# dispose idisposable using-statement

7
推荐指数
1
解决办法
1090
查看次数

在C#中使用(IDisposable obj = new ...)来编写流中的代码块(例如XML)

我已经开始使用实现IDisposable的类来使用using语句在流中编写块.这有助于保持正确的嵌套并避免丢失或错误放置的开始/结束部件.

基本上,构造函数编写块的开头(例如打开XML标记),Dispose()结束(例如关闭XML标记).示例是下面的UsableXmlElement(它适用于大型XML,因此内存中的LINQ to XML或XmlDocument不是选项).

但是,这些IDisposable不实现Microsoft推荐的复杂模式,使用Destructor/Finalizer,单独的Dispose(bool)方法和GC.SuppressFinalize().Dispose只是简单地写出end元素,就是这样.

这有什么不妥的,或者这是保持元素正确嵌套的好方法吗?

class UsableXmlElement : IDisposable
{
    private XmlWriter _xwriter;

    public UsableXmlElement(string name, XmlWriter xmlWriter)
    {
        _xwriter = xmlWriter;
        _xwriter.WriteStartElement(name);
    }

    public void WriteAttribute<T>(string name, T value)
    {
        _xwriter.WriteStartAttribute(name);
        _xwriter.WriteValue(value);
        _xwriter.WriteEndAttribute();
    }

    public void WriteValue<T>(T value)
    {
        _xwriter.WriteValue(value);
    }

    public void Dispose()
    {
        _xwriter.WriteEndElement();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

var xWriter = new XmlWriter(...)

using(var rootElement = new UsableXmlElement("RootElement", xWriter)
{
   rootElement.WriteAttribute("DocVersion", 123)
   using(var innerElement = new UsableXmlElement("InnerElement", xwriter)
   {
       // write anything inside Inner element
   }
} …
Run Code Online (Sandbox Code Playgroud)

c# xml idisposable using-statement stream

7
推荐指数
1
解决办法
344
查看次数

抛出了类型'System.OutOfMemoryException'的异常.C#使用IDataReader时

我有一个应用程序,我必须从DB获取大量数据.由于它未能获得所有这些行(它接近2,000,000行...),我在中断时将其剪切,并且每次执行sql查询时每次只获得200,000行.

我使用DataTable输入所有数据(意思是 - 所有2,000,000行应该在那里).

前几次运行很好.然后它以OutOfMemoryException失败.

我的代码如下:

private static void RunQueryAndAddToDT(string sql, string lastRowID, SqlConnection conn, DataTable dt, int prevRowCount)
    {
        if (string.IsNullOrEmpty(sql))
        {
            sql = generateSqlQuery(lastRowID);
        }

        if (conn.State == ConnectionState.Closed)
        {
            conn.Open();
        }

        using (IDbCommand cmd2 = conn.CreateCommand())
        {
            cmd2.CommandType = CommandType.Text;
            cmd2.CommandText = sql;
            cmd2.CommandTimeout = 0;

            using (IDataReader reader = cmd2.ExecuteReader())
            {
                while (reader.Read())
                {
                    DataRow row = dt.NewRow();
                    row["RowID"] = reader["RowID"].ToString();
                    row["MyCol"] = reader["MyCol"].ToString();
                    ... //In one of these rows it returns the exception.

                    dt.Rows.Add(row);
                } …
Run Code Online (Sandbox Code Playgroud)

c# sql exception datareader using-statement

7
推荐指数
2
解决办法
3万
查看次数

with-statement with async calls | Cancle操作?

我面临一个普遍的问题,我无法找到一个很好的例子来尝试为自己.谷歌不是一个帮助.

想象一下这样的结构:

MailMessage mail = new MailMessage(sender, receiver);
using(SmtpClient client = new SmtpClient())
{
    client.Host ...
    client.Port ...

    mail.subject ...
    mail.body ...

    client.SendAsync(mail);
}
Run Code Online (Sandbox Code Playgroud)

如果服务器很慢并且需要一段时间来接受邮件,该怎么办?是否有可能SmtpClient在操作完成之前进行处理?它会以任何方式被卷入或破坏吗?

对此有一般性的答案吗?这里的服务器速度太快,不知道怎么做试用.


如果考虑取消BackgroundWorker它总是完成当前的操作.在这里可能是相同的,或者可能不是......

c# dispose asynchronous using-statement

7
推荐指数
1
解决办法
191
查看次数

有没有办法使用动态创建目标的using语句?

假设我已经定义了一个类MyDisposable : IDisposable.我知道我可以IDisposableusing声明中提供一个硬编码的对象列表:

using (MyDisposable firstDisposable = new MyDisposable(),
    secondDisposable = new MyDisposable())
{
    // do something
}
Run Code Online (Sandbox Code Playgroud)

现在让我们说我有一些方法可以对我的一次性对象集合执行操作,我想在一个using语句中执行此操作.它可能看起来像这样(但是这当然不起作用,因为using块需要一个或多个IDisposable对象,而且我传递一个集合对象):

using (var myDisposables = GetMyDisposables())
{
    foreach (var myDisposable in myDisposables)
    {
        DoSomething(myDisposable);
        DoSomethingElse(myDisposable);
    }
}
Run Code Online (Sandbox Code Playgroud)

为清楚起见,其他方法如下:

static List<MyDisposable> GetMyDisposables()
{
    throw new NotImplementedException(); // return a list of MyDisposable objects
}

static void DoSomething(MyDisposable withMyDisposable)
{
    // something
}

static void DoSomethingElse(MyDisposable withMyDisposable)
{
    // something else
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以用using …

.net c# idisposable using-statement

7
推荐指数
1
解决办法
816
查看次数