Programing

C #에서 "사용"블록은 언제 사용해야합니까?

lottogame 2020. 10. 31. 09:12
반응형

C #에서 "사용"블록은 언제 사용해야합니까?


이 질문에 이미 답변이 있습니다.

"사용"블록을 사용해야하는 (또는 사용해서는 안되는) 특정 인스턴스가 있습니까?

using(SomeType t = new SomeType()){
    ...
}

SomeType클래스가 구현 IDisposable.


일부 개체는 작업을 마치면 취해야 할 조치가 필요합니다. 일반적으로 이는 개체가 폐기해야하는 일종의 리소스를 사용하기 때문입니다. 예를 들어, File 클래스의 파일 객체가 있고이 객체가 파일 시스템에서 파일을 여는 경우 파일 시스템의 파일을 다시 닫아야합니다.

방금 파일 객체를 떠났고 file.Close ()를 호출하는 것을 잊었다면 가비지 수집기 (GC)가 실행되고 파일 객체를 사용하는 것이 아무것도 없다는 것을 알아낼 때까지 정리되지 않습니다. 가비지 수집기가 실행되는시기는 CLR (공용 언어 런타임)에서 결정해야합니다. 파일 작업을 마친 후 GC가 한동안 실행되지 않으면 파일이 잠재적으로 오랫동안 열려있을 수 있습니다. 파일 개체가 많거나 파일을 열려고하는 경우 큰 문제가 될 수 있지만, 남겨둔 파일 개체가 여전히 주위에 있기 때문에 열 수 없습니다.

이 문제를 해결하기 위해 C #에는 IDisposable 인터페이스가 있습니다. 여기에는 Dispose라는 메서드가 하나 있습니다. 정리가 필요한 클래스는이 Dispose 메서드를 구현합니다. 이것은 리소스를 사용하는 모든 개체를 정리하는 표준 방법을 제공합니다. Dispose를 호출해야하는 클래스가 많이 있습니다. 이것의 문제는 코드가 Dispose 호출로 덮여 있으며 개체를 새로 작성하고 Dispose를 호출하여 정리하는 위치가 다르기 때문에 따라 가기가 까다 롭다는 것입니다. 따라서 코드를 많이 살펴보고 적절한 위치에 Dispose 호출이 있는지 확인해야했습니다.

이 문제를 해결하기 위해 C #은 'using'키워드를 도입했습니다. 개체를 새로 만든 위치에 'using'키워드를 배치하면 Dispose가 호출됩니다. using 문의 본문 내에 예외가 발생하더라도 Dispose가 어떤 일이 발생하더라도 호출되도록 보장합니다.

따라서 리소스를 할당하는 개체를 정리하려면 '사용'을 사용해야합니다.


using은 스택, 즉 함수에서 선언 된 객체에만 사용할 수 있습니다. 클래스의 멤버로 선언 된 객체에는 작동하지 않습니다. 그들에게는 Dispose를 직접 호출해야합니다. 클래스에서 Dispose를 구현해야 할 수 있습니다. 그래야 in이 필요한 모든 멤버 개체에서 Dispose를 호출 할 수 있습니다.


사용이 필요한 일반적인 개체는 파일, 데이터베이스 연결, 펜 및 브러시와 같은 그래픽 개체입니다.


때로는 두 작업이 함께 발생하기를 원할 때도 사용됩니다. 예를 들어 코드 블록이 입력되고 종료 될 때 로그 문을 작성하려는 경우 다음과 같이 사용할 수있는 로그 클래스를 작성할 수 있습니다.

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

로그 클래스의 생성자는 메시지를 작성하도록 만들 수 있으며 Dispose 메서드도 메시지를 작성할 수 있습니다. 종료 자 (~ Log)를 구현하여 Dispose 메서드가 호출되지 않으면 '사용'이 '새 로그'주변에 기억되는지 확인합니다.


어쨌든 / 블록 으로 감싸지 않는 한 using유형이 구현 될 때마다 사용하십시오 . 그러면 (원하는 모양에 따라) 블록을 사용할 수도 있습니다.IDisposabletrycatchfinally


난 당신이 때 다른 답변 많이 표시를 참조 해야using문을. 구체적 으로 진술을 하지 말아야 할 때를 언급하고 싶습니다 using.

현재 함수의 범위 밖에서 개체를 사용해야하는 경우 using블록 이 없습니다 . 좋은 예는 데이터베이스 연결을 반환하는 팩토리 메서드 또는 데이터 리더를 반환해야하는 메서드입니다. 두 경우 모두 using을 사용하여 개체를 생성 하면 메서드가 반환되기 전에 삭제되므로 메서드 외부에서 사용할 수 없습니다.

이제 여전히 이러한 개체가 삭제 되었는지 확인 하고 싶으 므로 using어딘가에 문 이 필요할 수 있습니다 . 객체가 실제로 생성되는 메서드에 포함하지 마십시오. 대신 함수 호출 자체를 using명령문으로 래핑 할 수 있습니다 .


SomeType이 IDisposable을 구현할 때.

이는 SomeType이 정리해야하는 관리되지 않는 리소스를 사용한다는 개발자의 단서입니다.


예:

        using(SqlConnection MyConnection = new SqlConnection("Connection string"))
        {
            MyConnection.Open();

            //...

            // 1. SQLConnection is a type that implements IDisposable
            // 2. So you can use MyConnection in a using statement
            // 3. When using block finishes, it calls Dispose method of 
            // SqlConnection class
            // 4. In this case, it will probably close the connection to 
            // the database and dispose MyConnection object

        }

IDisposable을 구현하는 고유 한 개체를 만들 수 있습니다.

public class MyOwnObjectThatImplementsIDisposable : IDisposable
{

    //... some code

    public void Dispose()
    {
        // Put here the code you want to be executed when the
        // using statement finish.
    }
}

따라서 using 문에서 MyOwnObjectThanImplementsIDisposable 유형의 개체를 사용할 수 있습니다.

        using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
        {

            // When the statement finishes, it calls the 
            // code you´ve writed in Dispose method
            // of MyOwnObjectThatImplementsIDisposable class
        }

도움이 되었기를 바랍니다


In this context the using statement is handy for types that implement IDisposable. When the code block exits the scope of the using statement, Dispose() is called implicitly. It's a good habit when working with objects you want to dispose immediately after use.


One specific instance in which you should be careful using a using block is with a WCF Service Client.

As noted in this MSDN article, wrapping a WCF client (which does implement IDisposable) in a using block could mask any errors which result in the client being left in a faulted state (like a timeout or communication problem). Long story short, when Dispose() is called, the client's Close() method fires, but throws and error because it's in a faulted state. The original exception is then masked by the second exception. Not good.

There are various workarounds out there, including one in the MSDN article itself. Others can be found at IServiceOriented and blog.davidbarret.net.

I prefer the last method, myself.


If you want a summary rule. Anytime an object using IDisposable where you would not have a catch, use using. Using, essentially, is this pattern:

try
{
  //instantiate and use object
}
finally
{
  //dispose object
}

If you do not need a catch, using can save you typing, which is a good thing.


The primary rule is: * Use USING statement when objects implements IDisposable interface.

This interface provides the Dispose method, which should release the object's resources. If this method is not invoked then the object will stay in memory as long, as CLR wants to perform garbage collection. If the programmer use the USING statement then on the end the object will be disposed, and all resources will be free.

It is very important that all resources that are no longer in use be free as soon as possible.

For more information about it just visit this link: microsoft


Maybe it is worth mentioning that underlying reason for adding “using” lo C# languge is following: some resources can be scarce enough that it doesn’t make sense to wait for GC to call IDisposable. For example, DB connections. If you use try/catch/finally you won’t end up with a dangling connection, but connection will be left hanging until GC doesn’t kick in and this can take a while (if you do not close it explicitly). IF you use "using" (excuse the pun) you will release the connection immediately even if you forgot to close it and even if some exception occured inside the using block.
Another reason, as previous post mentions, is that programmers do not always use finally to clean up. If not using finally in the case of exception you end up with leaking resources…


One situation is when you want to do something at the beginning of a code block, and then undo it at the end of the block, unconditionally (even if there is a throw).

The ctor for the disposable class that you build (and call within the using) would perform the action, and then the Dispose method would undo that action. This is typically how I use it.


Other people has mentioned about "IDisposable" already.

But one of the caveats when using "using" statement is that, any exceptions thrown within "using" will not be caught even thought "SomeType" will be disposed regardless.

So in the following snippet,

using (SomeType t = new SomeType()){
    throw new Exception("thrown within using");
}

throw new Exception("thrown within using"); should not be disregarded.


I would also add that use a using() statement if something implements IDispose and also if that something you want to dispose of holds on to NON-MANAGED resources like database connections and file handles.

If it's a normal object with say a List<T>, where T is like a Customer object that holds names and address, then you don't need to. The garbage collector is smart enough to manage this for you. But the garbage collector WILL NOT return connections to the connection pool or close file handles.

참고URL : https://stackoverflow.com/questions/567138/when-should-i-use-using-blocks-in-c

반응형