I saw similar problems on the internet, but couldn't really fit any of them to my code.
I'm running two hangfire jobs and sometimes they have to run at the same time.
RecurringJob.AddOrUpdate(()=>abill.CheckUserPayment(),Cron.Minutely);
RecurringJob.AddOrUpdate("CalculateUserCharge",()=>abill.CalculateUserCharge(DateTime.Today.AddDays(-1)),Cron.Daily(12,37),TimeZoneInfo.Utc);
RecurringJobs are launched from Configure() method from startup and I pass AccountBilling abill as a parameter.
AccountBilling.cs (whole code is not present)
public readonly EntityContext context;
private TBCPaymentOptions _tbcPaymentOptions = null;
public AccountBilling (EntityContext _context) {
context = _context;
}
public AccountBilling (EntityContext _context, IOptions<TBCPaymentOptions> tbcPaymentOptions) {
context = _context;
this._tbcPaymentOptions = tbcPaymentOptions.Value;
}
public void Save () {
try {
context.SaveChanges ();
} catch (Exception e) {
Console.WriteLine (e);
throw;
}
}
public void CalculateUserCharge (DateTime date) {
var latestJob = context.JobLogs.Include (c => c.JobStatus).OrderByDescending (c => c.StartDate).Where (c => c.JobId == (int) JobEnum.CloseDay).FirstOrDefault ();
var jobLog = new JobLog ();
jobLog.JobId = (int) JobEnum.CloseDay;
jobLog.JobStatusID = (int) JobStatusEnum.Active;
jobLog.StartDate = DateTime.Now;
context.Add (jobLog);
this.Save ();
Console.WriteLine ("Starting...");
if (latestJob != null && latestJob.JobStatusID == (int) JobStatusEnum.Active) {
jobLog.JobStatusID = (int) JobStatusEnum.Canceled;
jobLog.EndDate = DateTime.Now;
context.Update (jobLog);
context.SaveChanges ();
} else {
try {
var result = new List<GetActiveUserPackagesForOpenBillingPeriodResult> ();
using (var conn = new NpgsqlConnection (context.ConnectionString)) {
conn.Open ();
using (var cmd = new NpgsqlCommand ("\"GetActiveUserPackagesForOpenBillingPeriod\"", conn)) {
Console.WriteLine ("გავუშვი command");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue ("somedate", DateTime.Today);
var reader = cmd.ExecuteReader ();
string x = DBNull.Value.Equals (reader) ? " " : reader.ToString ();
if (x != null) {
while (reader.Read ()) {
result.Add (
new GetActiveUserPackagesForOpenBillingPeriodResult {
Amount = (decimal) reader["Amount"],
PackageID = (int) reader["PackageID"],
UserID = (int) reader["UserID"],
AccountID = (int) reader["AccountID"],
UserPackageStartDate = (DateTime) reader["UserPackageStartDate"],
}
);
}
}
conn.Close ();
}
var groupByResults = result.GroupBy (c => c.AccountID).Select (a => new {
accountId = a.Key,
lines = a.ToList ()
});
foreach (var group in groupByResults) {
var transactionHeader = new TransactionHeader () {
TransactionHeaderTypeID = (int) TransactionHeaderTypeEnum.Charge,
Date = date,
CorrectionDescription = null,
AccountID = group.accountId
};
foreach (var lineItem in group.lines) {
transactionHeader.TransactionLines.Add (new TransactionLine () {
UserID = lineItem.UserID,
PackageID = lineItem.PackageID,
Amount = this.CalculateUserChargeMethod (date, lineItem.Amount, lineItem.UserPackageStartDate)
});
}
transactionHeader.TotalAmount = transactionHeader.TransactionLines.Sum (c => c.Amount);
this.context.TransactionHeaders.Add (transactionHeader);
context.Add (transactionHeader);
this.Save ();
}
jobLog.EndDate = DateTime.Now;
jobLog.JobStatusID = (int) JobStatusEnum.Inactive;
context.Update (jobLog);
this.Save ();
ClosePeriodOnEndOfMonth (date, conn);
}
} catch (Exception ex) {
jobLog.EndDate = DateTime.Now;
jobLog.JobStatusID = (int) JobStatusEnum.Canceled;
jobLog.Comment = ex.ToString ();
context.Update (jobLog);
this.Save ();
//throw ex;
}
}
..........
public void CheckUserPayment () {
var Cert = new X509Certificate2 ("cert.p12", _tbcPaymentOptions.TBCPayCertificatePassword, X509KeyStorageFlags.MachineKeySet);
var time = DateTime.Now.AddMinutes (-5);
var latestJob = context.JobLogs.Include (c => c.JobStatus).OrderByDescending (c => c.StartDate).Where (c => c.JobId == (int) JobEnum.CheckPayment).FirstOrDefault ();
var jobLog = new JobLog ();
jobLog.JobId = (int) JobEnum.CheckPayment;
jobLog.JobStatusID = (int) JobStatusEnum.Active;
jobLog.StartDate = DateTime.Now;
context.Add (jobLog);
this.Save ();
if (latestJob != null && latestJob.JobStatusID == (int) JobStatusEnum.Active) {
jobLog.JobStatusID = (int) JobStatusEnum.Canceled;
jobLog.EndDate = DateTime.Now;
context.Update (jobLog);
this.Save ();
} else {
try {
var processingPayments = context.Payments.Where (c => c.AcceptanceAct.AcceptanceActStatusID == (int) AcceptanceActStatusEnum.Processing && c.CreatedDate < time).ToList ();
System.Console.WriteLine ("IN METHOD");
foreach (var item in processingPayments) {
System.Console.WriteLine ("Job Started");
this.CheckUserPaymentMethod (item.BankPaymentCode, item, _tbcPaymentOptions.AppPlatformIP, _tbcPaymentOptions.MerchantURL, Cert);
}
Console.WriteLine ("Job Done");
jobLog.JobStatusID = (int) JobStatusEnum.Inactive;
jobLog.EndDate = DateTime.Now;
context.Update (jobLog);
this.Save ();
//this.Save ();
} catch (Exception ex) {
jobLog.JobStatusID = (int) JobStatusEnum.Canceled;
jobLog.EndDate = DateTime.Now;
jobLog.Comment = ex.ToString ();
context.Update (jobLog);
this.Save ();
}
}
}
Startup.cs (whole code is not present):
services.AddEntityFrameworkNpgsql ()
.AddDbContext<EntityContext> (
options => options.UseNpgsql (connectionString)
);