{"record":{"id":"a2fc1c805a4fee9e","repo":"JeffreySu/WeiXinMPSDK","slug":"onexecutedasync","errorCode":null,"errorMessage":"请使用异步方法 OnExecutedAsync()","messagePattern":"请使用异步方法 OnExecutedAsync\\(\\)","errorType":"exception","errorClass":"MessageHandlerException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.MP/Senparc.Weixin.MP/MessageHandlers/MessageHandler.cs","lineNumber":364,"sourceCode":"        //}\n\n        #endregion\n\n        #region 消息处理\n\n        /// <summary>\n        /// OnExecuting\n        /// </summary>\n        [Obsolete(\"请使用异步方法 OnExecutingAsync()\", true)]\n        public override void OnExecuting()\n        {\n            throw new MessageHandlerException(\"请使用异步方法 OnExecutingAsync()\");\n        }\n\n        [Obsolete(\"请使用异步方法 OnExecutedAsync()\", true)]\n        public override void OnExecuted()\n        {\n            throw new MessageHandlerException(\"请使用异步方法 OnExecutedAsync()\");\n        }\n\n        #endregion }\n    }\n}\n","sourceCodeStart":346,"sourceCodeEnd":370,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.MP/Senparc.Weixin.MP/MessageHandlers/MessageHandler.cs#L346-L370","documentation":"The synchronous OnExecuted override in the MP MessageHandler is marked [Obsolete(..., true)] and always throws MessageHandlerException, mirroring error 56 but for the post-processing hook. The library only supports the async lifecycle: logic that used to run after message handling must live in OnExecutedAsync.","triggerScenarios":"Calling messageHandler.OnExecuted() directly, overriding it and invoking base behavior, or running a legacy synchronous Execute pipeline that still calls OnExecuted after message handling completes.","commonSituations":"Upgraded Senparc.Weixin packages where old sync controller code (commonly in ASP.NET WeixinController or WxOpen samples) still invokes the sync pipeline; copy-pasted legacy sample code that performs post-processing via OnExecuted.","solutions":["Use the async pipeline (ExecuteAsync) so OnExecutedAsync runs instead of the throwing OnExecuted.","Relocate post-processing logic from OnExecuted overrides into OnExecutedAsync in your handler subclass.","Search and update all call sites flagged by the compiler as obsolete-with-error for OnExecuted.","If a third-party wrapper calls the sync hooks, upgrade or replace that wrapper with an async-compatible one."],"exampleFix":"// before\nmessageHandler.Execute();\nmessageHandler.OnExecuted();\n\n// after\nawait messageHandler.ExecuteAsync(cancellationToken);\n\npublic override async Task OnExecutedAsync(CancellationToken ct)\n{\n    // post-processing here\n}","handlingStrategy":"type-guard","validationCode":"// ensure no code path references the sync hook\nif (typeof(MyHandler).GetMethod(\"OnExecuted\", Type.EmptyTypes) != null)\n    throw new InvalidOperationException(\"Override OnExecutedAsync, not OnExecuted\");","typeGuard":"bool IsPostProcessingAsync(MyHandler h) =>\n    h.GetType().GetMethod(\"OnExecutedAsync\", new[] { typeof(CancellationToken) })\n        .GetBaseDefinition().DeclaringType != typeof(object);","tryCatchPattern":"try { await messageHandler.ExecuteAsync(ct); }\ncatch (MessageHandlerException ex) when (ex.Message.Contains(\"OnExecutedAsync\"))\n{\n    logger.LogError(ex, \"Sync OnExecuted invoked; migrate to ExecuteAsync\");\n    throw;\n}","preventionTips":["Move all post-processing into OnExecutedAsync overrides.","Grep codebase for '.OnExecuted(' during upgrades and remove sync calls.","Treat CS0619 compiler errors as mandatory fixes before release.","Use ExecuteAsync exclusively for the handler lifecycle."],"tags":["wechat","messagehandler","async","obsolete-api","deprecated"],"backgroundTag":"deprecated-api-usage","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}