Я создаю программу выполнения заданий базы данных, которая позволит пользователям автоматизировать извлечение наборов данных из различных интерфейсов API и импортировать их в нашу базу данных.
После загрузки всех заданий при запуске приложения фоновый режимрабочий engine_JobTrigger
запускает цикл, который несколько раз проверяет дату и время и сравнивает их с NextExecutionTime
каждого задания в хранилище.Если срабатывает триггер, фоновый поток создает новый экземпляр BackgroundWorker
(необходим для запуска других заданий), добавляет обработчик к DoWork
на Job.ExecuteJob
и начинает выполнение работника:
'Class definition for Job Executor Engine
Public Class engine_JobExecutorArgs
Public SourceJob As Job = Nothing
Public ExecutedAs As String = ""
Public ExecuteStartTime As DateTime = Nothing
End Class
.............................................
engine_JobTrigger.DoWork \|/
.............................................
While Not engine.Cancel = True
Dim jobsToStart As New List(Of Integer)
If JobController.Jobs.Count > 0 Then
For Each process As Job In JobController.Jobs
If process.Schedule.isNowNextExecutionTime(process.LastExecutionTime) And Not process.isExecuting Then jobsToStart.Add(process.JobID)
Next
End If
If jobsToStart.Count > 0 Then
For Each JobID As Integer In jobsToStart
'Argument passed to BackgroundWorker
Dim newJobExecutorArgs As New engine_JobExecutorArgs() With {
.SourceJob = JobController.GetJob(CType(JobID, Integer)),
.ExecutedAs = Security.Principal.WindowsIdentity.GetCurrent().Name.ToString(),
.ExecuteStartTime = Now
}
Dim newJobExecutor As New System.ComponentModel.BackgroundWorker()
AddHandler newJobExecutor.DoWork, AddressOf newJobExecutorArgs.SourceJob.ExecuteJob
AddHandler newJobExecutor.RunWorkerCompleted, AddressOf engine_JobExecutor_RunWorkerCompleted
newJobExecutor.RunWorkerAsync(newJobExecutorArgs)
Next
Else
Threading.Thread.Sleep(200)
End If
End While
Все хорошо, пока я не войду в функцию Job.ExecuteJob
и попытаюсь объявить аргумент, переданный недавно созданному BackgroundWorker
:
Dim inputArgs As MainWindow.engine_JobExecutorArgs = DirectCast(e.Argument(0), MainWindow.engine_JobExecutorArgs)
System.MissingMemberException
HResult=0x80131512
Message=No default member found for type 'engine_JobExecutorArgs'.
Source=Microsoft.VisualBasic
StackTrace:
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.CallMethod(Container BaseReference, String MethodName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack, BindingFlags InvocationFlags, Boolean ReportErrors, ResolutionFailure& Failure)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.InternalLateIndexGet(Object Instance, Object[] Arguments, String[] ArgumentNames, Boolean ReportErrors, ResolutionFailure& Failure, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateInvokeDefault(Object Instance, Object[] Arguments, String[] ArgumentNames, Boolean ReportErrors, Boolean[] CopyBack)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateIndexGet(Object Instance, Object[] Arguments, String[] ArgumentNames)
at Mastermind.Job.ExecuteJob(Object sender, DoWorkEventArgs e) in ...Mastermind\JobObject.vb:line 184
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
Есть ли у кого-нибудь какие-либо предложения??Я хотел бы продолжать использовать объект класса в качестве аргумента для моих BackgroundWorker
s. Это поможет мне позже, когда я закончу и буду нуждаться в реализации новых функций.Как передать пользовательский класс в качестве аргумента для RunWorkerAsync в этом сценарии?Спасибо за любые советы заранее!
РЕДАКТИРОВАТЬ: Как только ошибка возникает, я могу успешно оценить e.Argument(0)
и просмотреть значения в классе через IDE.