{"record":{"id":"1aacc71337006438","repo":"abpframework/abp","slug":"could-not-find-dowork-method-on-type-workertyp","errorCode":null,"errorMessage":"Could not find 'DoWork' method on type '{workerType.FullName}'.","messagePattern":"Could not find 'DoWork' method on type '(.+?)'\\.","errorType":"exception","errorClass":"AbpException","httpStatus":null,"severity":"critical","filePath":"framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQPeriodicBackgroundWorkerInvoker.cs","lineNumber":47,"sourceCode":"                if (method == null)\n                {\n                    throw new AbpException($\"Could not find 'DoWorkAsync' method on type '{workerType.FullName}'.\");\n                }\n\n                var instanceParam = Expression.Parameter(typeof(AsyncPeriodicBackgroundWorkerBase), \"worker\");\n                var contextParam = Expression.Parameter(typeof(PeriodicBackgroundWorkerContext), \"context\");\n                var call = Expression.Call(Expression.Convert(instanceParam, workerType), method, contextParam);\n                var lambda = Expression.Lambda<Func<AsyncPeriodicBackgroundWorkerBase, PeriodicBackgroundWorkerContext, Task>>(call, instanceParam, contextParam);\n                _doWorkAsyncDelegate = lambda.Compile();\n                break;\n            }\n            case PeriodicBackgroundWorkerBase:\n            {\n                var workerType = worker.GetType();\n                var method = workerType.GetMethod(\"DoWork\", BindingFlags.Instance | BindingFlags.NonPublic);\n                if (method == null)\n                {\n                    throw new AbpException($\"Could not find 'DoWork' method on type '{workerType.FullName}'.\");\n                }\n\n                var instanceParam = Expression.Parameter(typeof(PeriodicBackgroundWorkerBase), \"worker\");\n                var contextParam = Expression.Parameter(typeof(PeriodicBackgroundWorkerContext), \"context\");\n                var call = Expression.Call(Expression.Convert(instanceParam, workerType), method, contextParam);\n                var lambda = Expression.Lambda<Action<PeriodicBackgroundWorkerBase, PeriodicBackgroundWorkerContext>>(call, instanceParam, contextParam);\n                _doWorkDelegate = lambda.Compile();\n                break;\n            }\n        }\n    }\n\n    public virtual async Task DoWorkAsync(TickerFunctionContext context, CancellationToken cancellationToken = default)\n    {\n        var workerContext = new PeriodicBackgroundWorkerContext(ServiceProvider);\n        switch (Worker)\n        {\n            case AsyncPeriodicBackgroundWorkerBase asyncPeriodicBackgroundWorker:","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/abpframework/abp/blob/7ed43b1931b9df46a50c0c59148a18645641d0df/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQPeriodicBackgroundWorkerInvoker.cs#L29-L65","documentation":"Thrown by AbpTickerQPeriodicBackgroundWorkerInvoker when reflecting over a PeriodicBackgroundWorkerBase subclass and the non-public instance method 'DoWork' cannot be found. ABP compiles a delegate to this protected method to drive the worker's periodic execution. The method is part of the ABP base class contract; its absence indicates a version mismatch or an incorrectly overridden worker.","triggerScenarios":"Registering a worker derived from the synchronous PeriodicBackgroundWorkerBase whose DoWork(PeriodicBackgroundWorkerContext) method is not resolvable via BindingFlags.Instance | BindingFlags.NonPublic. Happens when the ABP packages are version-inconsistent or a subclass shadowed the method incorrectly.","commonSituations":"Mixing ABP package versions where the base class no longer declares DoWork as protected. Overriding DoWork but changing its access modifier (e.g. making it private or renaming it). A weaving/proxy layer that altered method metadata.","solutions":["Align all ABP package versions so PeriodicBackgroundWorkerBase.DoWork exists with the expected signature and accessibility.","If overriding, use 'protected override void DoWork(PeriodicBackgroundWorkerContext workerContext)' exactly.","Prefer AsyncPeriodicBackgroundWorkerBase over the synchronous base for new workers, as it is the recommended base class."],"exampleFix":"// before — wrong signature/access\npublic class MyWorker : PeriodicBackgroundWorkerBase\n{\n    private void DoWork() { ... } // wrong\n}\n\n// after\npublic class MyWorker : PeriodicBackgroundWorkerBase\n{\n    Period = 60000;\n    protected override void DoWork(PeriodicBackgroundWorkerContext workerContext) { ... }\n}","handlingStrategy":"validation","validationCode":"var method = worker.GetType().GetMethod(\"DoWork\", BindingFlags.Instance | BindingFlags.NonPublic);\nif (method == null)\n{\n    throw new InvalidOperationException($\"Worker {worker.GetType().FullName} is missing DoWork; check ABP package versions and method signature.\");\n}","typeGuard":"static bool HasDoWork(Type workerType) => workerType.GetMethod(\"DoWork\", BindingFlags.Instance | BindingFlags.NonPublic) != null;","tryCatchPattern":null,"preventionTips":["Keep all ABP NuGet packages version-aligned.","Override DoWork with the exact 'protected override void DoWork(PeriodicBackgroundWorkerContext)' signature.","Prefer the async base class for new workers to avoid the synchronous reflection path."],"tags":["tickerq","background-workers","reflection","version-mismatch","internal-api"],"backgroundTag":null,"analyzedSha":"7ed43b1931b9df46a50c0c59148a18645641d0df","analyzedAt":"2026-08-13T16:26:11.351Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}