MeWrite Docs

C#: ObjectDisposedException

C#で破棄されたオブジェクトにアクセスした際のエラー原因と解決策

概要

Dispose()が呼ばれた後のオブジェクトにアクセスした際に発生するエラーです。

エラーメッセージ

``` System.ObjectDisposedException: Cannot access a disposed object. Object name: ‘HttpClient’. ```

原因

  1. using後のアクセス: usingブロック外での使用
  2. 非同期処理の競合: Disposeとawaitのタイミング
  3. 共有リソースの早期破棄: シングルトンのHttpClient等
  4. イベントハンドラでの参照: 破棄後もイベントが発火

解決策

1. usingのスコープを確認

```csharp // 悪い例 HttpResponseMessage response; using (var client = new HttpClient()) { response = await client.GetAsync(url); } var content = await response.Content.ReadAsStringAsync(); // エラー

// 良い例 using (var client = new HttpClient()) { var response = await client.GetAsync(url); var content = await response.Content.ReadAsStringAsync(); // OK } ```

2. HttpClientは共有する

```csharp // 悪い例: 毎回新規作成 public async Task GetData() { using var client = new HttpClient(); return await client.GetStringAsync(url); }

// 良い例: IHttpClientFactoryを使用 public class MyService { private readonly HttpClient _client;

public MyService(IHttpClientFactory factory)
{
    _client = factory.CreateClient();
}

public async Task<string> GetData()
{
    return await _client.GetStringAsync(url);
}

} ```

3. 非同期Dispose (C# 8.0+)

```csharp public class AsyncResource : IAsyncDisposable { public async ValueTask DisposeAsync() { await CleanupAsync(); } }

// 使用 await using var resource = new AsyncResource(); await resource.DoWorkAsync(); ```

4. 破棄チェックを追加

```csharp public class MyResource : IDisposable { private bool _disposed = false;

public void DoWork()
{
    if (_disposed)
        throw new ObjectDisposedException(nameof(MyResource));
    // 処理
}

public void Dispose()
{
    _disposed = true;
    // クリーンアップ
}

} ```

よくある間違い

  • HttpClientを毎回newしてDispose
  • 非同期メソッドの結果を待たずにDispose
  • Disposeの順序が不適切

関連エラー

関連エラー

C# の他のエラー

最終更新: 2025-12-10