What Happens If I Return Before the End of Using Statement? Will the Dispose Be Called

What happens if i return before the end of using statement? Will the dispose be called?

Yes, Dispose will be called. It's called as soon as the execution leaves the scope of the using block, regardless of what means it took to leave the block, be it the end of execution of the block, a return statement, or an exception.

As @Noldorin correctly points out, using a using block in code gets compiled into try/finally, with Dispose being called in the finally block. For example the following code:

using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}

effectively becomes:

MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}

So, because finally is guaranteed to execute after the try block has finished execution, regardless of its execution path, Dispose is guaranteed to be called, no matter what.

For more information, see this MSDN article.

Addendum:
Just a little caveat to add: because Dispose is guaranteed to be called, it's almost always a good idea to ensure that Dispose never throws an exception when you implement IDisposable. Unfortunately, there are some classes in the core library that do throw in certain circumstances when Dispose is called -- I'm looking at you, WCF Service Reference / Client Proxy! -- and when that happens it can be very difficult to track down the original exception if Dispose was called during an exception stack unwind, since the original exception gets swallowed in favor of the new exception generated by the Dispose call. It can be maddeningly frustrating. Or is that frustratingly maddening? One of the two. Maybe both.

What happens if I called Dispose() before using statement end?

The documentation for IDisposable.Dispose states:

If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.

Assuming IDisposable is implemented correctly, this use is safe. Dispose will be called a second time, and will do nothing that second time.

Will using destroy data if return will be inside

using is a Syntactic sugar, it need to contain an object which implements IDisposable interface when you leave the using scope .net will call the IDisposable.Dispose method Automatically.

Here is a sample c# online

when the program leave Test method. .net will call IDisposable.Dispose method Automatically

Refactoring: using statement without scope, when does the implicit `Dispose` call happen?

Resharper suggests C# 8.0 using declaration feature:

 public async Task<Result> Handle(CancelInitiatedCashoutCommand command, 
CancellationToken cancellationToken)
{
using var scope = ...;
...
} // <- scope will be Disposed on leaving its scope (here on Handle method's scope)

Will the discard variable _ call Dispose() when put in a using statement?

It is called - check the decompiled code on sharplab (or write a simple test snippet). But if you don't need the variable you can just skip the discard completely and write:

using (ZipFile.Open(filename, ZipArchiveMode.Update)) 
{

}

With the same effect.

Does Dispose still get called when exception is thrown inside of a using statement?

Yes, using wraps your code in a try/finally block where the finally portion will call Dispose() if it exists. It won't, however, call Close() directly as it only checks for the IDisposable interface being implemented and hence the Dispose() method.

See also:

  • Intercepting an exception inside IDisposable.Dispose
  • What is the proper way to ensure a SQL connection is closed when an exception is thrown?
  • C# "Using" Syntax
  • C# USING keyword - when and when not to use it?
  • 'using' statement vs 'try finally'
  • What is the C# Using block and why should I use it?
  • Disposable Using Pattern
  • Does End Using close an open SQL Connection

Using statement vs. IDisposable.Dispose()

using is basically the equivalent of:

try
{
// code
}
finally
{
obj.Dispose();
}

So it also has the benefit of calling Dispose() even if an unhandled exception is thrown in the code within the block.

Will my c# 8.0 using declaration dispose my object correctly? When is it disposed?

using var clientWebSocket = new ClientWebSocket(); is just syntactical sugar, it's short hand for:

private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
using( var clientWebSocket = new ClientWebSocket())
{
_clientWebSocket = clientWebSocket;

try
{
await clientWebSocket.ConnectAsync(new Uri(_url), cancellationToken);
}
catch
{
return false;
}

try
{
while (clientWebSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested)
{
var bytesReceived = new ArraySegment<byte>(new byte[1024]);
var receiveResult = await clientWebSocket.ReceiveAsync(bytesReceived, cancellationToken);
var message = Encoding.UTF8.GetString(bytesReceived.Array, 0, receiveResult.Count);

...
}
}
catch
{
return false;
}

try
{
if (clientWebSocket.State == WebSocketState.Open)
{
await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None);
}
}
catch
{
return false;
}

return true;

}
}

which is short hand for:

private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
var clientWebSocket = new ClientWebSocket();
try
{
_clientWebSocket = clientWebSocket;

try
{
await clientWebSocket.ConnectAsync(new Uri(_url), cancellationToken);
}
catch
{
return false;
}

try
{
while (clientWebSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested)
{
var bytesReceived = new ArraySegment<byte>(new byte[1024]);
var receiveResult = await clientWebSocket.ReceiveAsync(bytesReceived, cancellationToken);
var message = Encoding.UTF8.GetString(bytesReceived.Array, 0, receiveResult.Count);

...
}
}
catch
{
return false;
}

try
{
if (clientWebSocket.State == WebSocketState.Open)
{
await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None);
}
}
catch
{
return false;
}

return true;

}
finally
{
if (clientWebSocket != null) {
((IDisposable)clientWebSocket).Dispose();
}
}
}

I think it's also worth highlighting this comment:

I'm more worried that you're disposing something that you've assigned
to the field _clientWebSocket

clientWebSocket is going to get disposed, but because you assign _clientWebSocket to this (_clientWebSocket = clientWebSocket;), the object that varibale is pointing at will get disposed as well! They are the same thing. They reference each other. I'd imagine this is not what you want to happen here, but it's hard to tell from the code you've shared.

What happens to a Process in a using statement without WaitForExit()?

One should separate the OS process that is running on your system from the Process object that represents a "handle" to it in your program:

  • The process continues running until it completes, or you kill it using OS-specific methods
  • The Process object gets disposed, so your program can no longer interact with the OS process.

Call of Dispose() method on the Process object does not kill the OS process.



Related Topics



Leave a reply



Submit