Correct way of using Using with inner using

时间:2016-04-15 14:54:19

标签: c# .net using

I am downloading some XML string from a URL and I need to parse it. So, I have the following syntax:

// Code Section 1    
using (var webClient = new WebClient())
{
    response = await webClient.DownloadStringTaskAsync(new Uri(myUrl));
}

SyndicationFeed myFeed;
using (XmlTextReader reader = new XmlTextReader(new StringReader(response)))
{
    myFeed= SyndicationFeed.Load(reader);
}

if(myFeed != null)
{
    // Do something
}

But, a teammate has raised a concern that code will look better if I do

// Code Section 2
using (var webClient = new WebClient())
{
    string response = await webClient.DownloadStringTaskAsync(new Uri(myUrl));

    using (XmlTextReader reader = new XmlTextReader(new StringReader(response)))
    {
        SyndicationFeed myFeed= SyndicationFeed.Load(reader);
        if(myFeed != null)
        {
            // Do something
        }
    }   
}

Logically, they perform the same task, perhaps there might be some performance impact.

My questions are:

  • What is the correct way of using using with an inner using?
  • Should I "release" the memory as soon as possible, which means put as fewer logic as possible inside the using?

3 个答案:

答案 0 :(得分:3)

What is the correct way of using using with an inner using?

Well, you don't have an inner using here. Your two using blocks are completely independent.

If you had two dependent using blocks (for example database connection and recordset), your second approach would be mandatory.

Right now, it's a matter of style. Strictly speaking, the first approach is a bit better because it's disposing resources earlier, but in this case, it really does not matter. Pick the one you like best.

答案 1 :(得分:2)

Generally, the example under (1) ensures a better separation of concerns. As a practical example, it's easier to decompose such code into separate methods. The logical coupling between each using statement is lower, and there is no implied nesting of scopes that enforces a reverse order

On the other hand, the code under example (2) will lead to a longer life-time of the outer resource. In practice, it may and may not have a significant impact on performance and resource consumption.

As a rule of thumb, I would prefer option (1) as it is less coupled, allows better resource management, separates concerns, and is easier to refactor.

Note: As nvoigt correctly points out in his answer, the applicability of (1) over (2) in your specific situation is possible thanks to the fact the resources are not dependent on each other.

答案 2 :(得分:1)

I think it is better to call dispose on an object as soon as nobody use it again. So the first approach sounds like a better one to me.
I will also extract the logic in two separate method.

public static async string GetWebData(string url)
{
    using (var webClient = new WebClient())
    {
        return await webClient.DownloadStringTaskAsync(new Uri(url));
    }
}

public static async SyndicationFeed ProcessWebData(string data)
{
    using (XmlTextReader reader = new XmlTextReader(new StringReader(response)))
    {
        return SyndicationFeed.Load(reader);
    }
}

and then the code will be like

var response = await GetWebData(myUrl);
var myFeed = await ProcessWebData(response);
if (myFeed != null)
{
    // Do something
}