JeffreySu/WeiXinMPSDK · error · ObjectDisposedException

ObjectDisposedException (MsgAuditFinanceClient)

Error message

ObjectDisposedException (MsgAuditFinanceClient)

What it means

MsgAuditFinanceClient wraps a native SDK handle; ThrowIfDisposed throws ObjectDisposedException naming MsgAuditFinanceClient when GetChatData, DecryptData, or GetMediaData is called after Dispose. Native resources cannot be used after the SDK instance is destroyed.

Solutions

  1. Keep the client alive for the full duration of its use; move it out of the using scope or use explicit lifecycle management
  2. Register the client in DI as a singleton/scoped service and let the container dispose it
  3. Recreate a new MsgAuditFinanceClient if the previous one was disposed
  4. Guard background tasks against using clients whose lifetime ended

Example fix

// before
MsgAuditFinanceClient client;
using (client = new MsgAuditFinanceClient(options)) { }
client.GetChatData(...); // disposed
// after
using var client = new MsgAuditFinanceClient(options);
client.GetChatData(...); // all usage inside lifetime
Defensive patterns

Strategy: type-guard

Validate before calling

if (_client is null || _clientDisposed) throw new InvalidOperationException("client lifetime ended");

Type guard

bool Usable(MsgAuditFinanceClient? c) => c is not null && !c.Disposed; // track disposal in your wrapper if the client lacks a public flag

Try / catch

try { var data = client.GetChatData(...); }
catch (ObjectDisposedException) { client = new MsgAuditFinanceClient(options); /* recreate and retry once */ }

Prevention

When it happens

Trigger: Calling any data API after client.Dispose() — e.g. reusing a client stored in a field after a using block ended, or a long-lived background job holding a disposed client.

Common situations: 'using var client = ...' scope ending while async continuations still use the client, singleton service disposed by DI container while background threads still reference it, or accidental early Dispose.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of JeffreySu/WeiXinMPSDK@be573f6f94 (2026-09-12). Data as JSON: /api/errors/b206a4da6fa957f9. Report an issue: GitHub.

Appendix: source

Thrown at src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceClient.cs:317

            if (handle == IntPtr.Zero)
            {
                throw new InvalidOperationException($"Finance SDK 的 {operation} 操作返回了空指针。");
            }
        }

        private static void ThrowIfNativeError(int errorCode, string operation)
        {
            if (errorCode != 0)
            {
                throw new MsgAuditFinanceException(errorCode, operation);
            }
        }

        private void ThrowIfDisposed()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(nameof(MsgAuditFinanceClient));
            }
        }

        private void ReleaseResources(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            _disposed = true;
            var nativeApi = _nativeApi;
            _nativeApi = null;
            if (nativeApi == null)
            {
                return;
            }

View on GitHub (pinned to be573f6f94)