Skip to content

Commit

Permalink
[UUF] Update example to match text (#44442)
Browse files Browse the repository at this point in the history
  • Loading branch information
gewarren authored Jan 21, 2025
1 parent ac8b832 commit 9d498cf
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 18 deletions.
14 changes: 7 additions & 7 deletions docs/standard/garbage-collection/implementing-dispose.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,31 +54,31 @@ Method signatures are:

Because the `public`, non-virtual (`NotOverridable` in Visual Basic), parameterless `Dispose` method is called when it's no longer needed (by a consumer of the type), its purpose is to free unmanaged resources, perform general cleanup, and to indicate that the finalizer, if one is present, doesn't have to run. Freeing the actual memory associated with a managed object is always the domain of the [garbage collector](index.md). Because of this, it has a standard implementation:

:::code language="csharp" source="../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.disposable/cs/Disposable.cs" id="Dispose":::
:::code language="vb" source="../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.disposable/vb/Disposable.vb" id="Dispose":::
:::code language="csharp" source="./snippets/dispose-pattern/csharp/Disposable.cs" id="Dispose":::
:::code language="vb" source="./snippets/dispose-pattern/vb/Disposable.vb" id="Dispose":::

The `Dispose` method performs all object cleanup, so the garbage collector no longer needs to call the objects' <xref:System.Object.Finalize%2A?displayProperty=nameWithType> override. Therefore, the call to the <xref:System.GC.SuppressFinalize%2A> method prevents the garbage collector from running the finalizer. If the type has no finalizer, the call to <xref:System.GC.SuppressFinalize%2A?displayProperty=nameWithType> has no effect. The actual cleanup is performed by the `Dispose(bool)` method overload.

### The Dispose(bool) method overload

In the overload, the `disposing` parameter is a <xref:System.Boolean> that indicates whether the method call comes from a <xref:System.IDisposable.Dispose%2A> method (its value is `true`) or from a finalizer (its value is `false`).

:::code language="csharp" source="../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.disposable/cs/Disposable.cs" id="DisposeBool":::
:::code language="vb" source="../../../samples/snippets/visualbasic/VS_Snippets_CLR/conceptual.disposable/vb/Disposable.vb" id="DisposeBool":::
:::code language="csharp" source="./snippets/dispose-pattern/csharp/Disposable.cs" id="DisposeBool":::
:::code language="vb" source="./snippets/dispose-pattern/vb/Disposable.vb" id="DisposeBool":::

> [!IMPORTANT]
> The `disposing` parameter should be `false` when called from a finalizer, and `true` when called from the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method. In other words, it is `true` when deterministically called and `false` when non-deterministically called.
> The `disposing` parameter should be `false` when called from a finalizer, and `true` when called from the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method. In other words, it is `true` when deterministically called and `false` when nondeterministically called.
The body of the method consists of three blocks of code:

- A block for conditional return if object is already disposed.
- A block that frees unmanaged resources. This block executes regardless of the value of the `disposing` parameter.
- A conditional block that frees managed resources. This block executes if the value of `disposing` is `true`. The managed resources that it frees can include:

- **Managed objects that implement <xref:System.IDisposable>.** The conditional block can be used to call their <xref:System.IDisposable.Dispose%2A> implementation (cascade dispose). If you have used a derived class of <xref:System.Runtime.InteropServices.SafeHandle?displayProperty=nameWithType> to wrap your unmanaged resource, you should call the <xref:System.Runtime.InteropServices.SafeHandle.Dispose?displayProperty=nameWithType> implementation here.

- **Managed objects that consume large amounts of memory or consume scarce resources.** Assign large managed object references to `null` to make them more likely to be unreachable. This releases them faster than if they were reclaimed nondeterministically.

- A block that frees unmanaged resources. This block executes regardless of the value of the `disposing` parameter.

If the method call comes from a finalizer, only the code that frees unmanaged resources should execute. The implementer is responsible for ensuring that the false path doesn't interact with managed objects that may have been disposed. This is important because the order in which the garbage collector disposes managed objects during finalization is nondeterministic.

## Cascade dispose calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ protected virtual void Dispose(bool disposing)

if (disposing)
{
// TODO: dispose managed state (managed objects).
// Dispose managed state (managed objects).
// ...
}

// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
// Free unmanaged resources.
// ...

_disposed = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@

' <SnippetDisposeBool>
Protected Overridable Sub Dispose(disposing As Boolean)
If disposed Then Exit Sub
If disposed Then Exit Sub

' A block that frees unmanaged resources.

If disposing Then
' Deterministic call…
' A conditional block that frees managed resources.
End If

disposed = True

' Free managed resources.
' ...

End If

' Free unmanaged resources.
' ...

disposed = True
End Sub
' </SnippetDisposeBool>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

</Project>

0 comments on commit 9d498cf

Please sign in to comment.