private static void OnSendingCompleted(MaillingCommunication com) { if (SendingCompleted != null) Task.Factory.StartNew(() => { SendingCompleted(null, com); }); }
private static void OnSendingCancelled(MaillingCommunication com, Exception ex) { if (SendingCancelled != null) Task.Factory.StartNew(() => { SendingCancelled(null, new SendingCancelledEventArgs { CancelledCommunication = com, Reason = ex }); }); }
public static DateTimeOffset ScheduleCommunication(MaillingCommunication com) { Contract.Requires(com != null); ITrigger trigger = TriggerBuilder.Create() .WithCronSchedule(com.ScheduleString) .Build(); IJobDetail detail = new JobDetailImpl("senderJob", typeof(SenderJob)); detail.JobDataMap.Add("Communication", com); items.Add(new Item { Com = com, Key = trigger.Key }); return QuartzSheduler.ScheduleJob(detail, trigger); }
public static void UnscheduleCommunication(MaillingCommunication com) { Contract.Requires(com != null); try { Item i = items.Single(it => it.Com == com); QuartzSheduler.UnscheduleJob(i.Key); items.RemoveAll(it => it.Com == com); } catch (Exception ex) { throw new Exception("Error while unscheduling communication", ex); } }
public async static Task SendCommunication(MaillingCommunication communication) { Contract.Requires(communication != null); if (communication.State == SendingState.Sending) throw new Exception("Communication is already sending."); await Task.Factory.StartNew((a) => { IEnumerable<IModifier<TemplateMessage>> preModifiers = communication.PreModifiers.Concat(PreModifiers); IEnumerable<IModifier<MailMessage>> postModifiers = communication.PostModifiers.Concat(PostModifiers); TemplateMessage templateMessage = TemplateMessage.ExecuteModifiers(communication.Message, preModifiers); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); var sender = new ActionBlock<MailMessage>((message) => { bool success = true; try { SmtpSender.Send(message); } catch { success = false; } communication.AddSendResult(new MaillingCommunication.SendResult(DateTime.Now, success)); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded, CancellationToken = cancellationTokenSource.Token, SingleProducerConstrained = true, BoundedCapacity = DataflowBlockOptions.Unbounded }); DateTime lastItem = DateTime.MinValue; var delayer = new TransformBlock<MailMessage, MailMessage>( async x => { var waitTime = lastItem + communication.SendDelay - DateTime.UtcNow; if (waitTime > TimeSpan.Zero) await Task.Delay(waitTime); lastItem = DateTime.UtcNow; return x; }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1, CancellationToken = cancellationTokenSource.Token, SingleProducerConstrained = true } ); var modifier = new TransformBlock<MailMessage, MailMessage>( (mess) => { return mess.ExecuteModifiers(postModifiers); }, new ExecutionDataflowBlockOptions { CancellationToken = cancellationTokenSource.Token, BoundedCapacity = DataflowBlockOptions.Unbounded, SingleProducerConstrained = true, MaxDegreeOfParallelism = 1 } ); var mapper = new TransformBlock<dynamic, MailMessage>( (row) => { object data = communication.DataSchema.MapData(row); return templateMessage.Gen(data); }, new ExecutionDataflowBlockOptions { CancellationToken = cancellationTokenSource.Token, BoundedCapacity = DataflowBlockOptions.Unbounded, SingleProducerConstrained = true, MaxDegreeOfParallelism = 1 } ); mapper.LinkTo(modifier, new DataflowLinkOptions { PropagateCompletion = true }); modifier.LinkTo(delayer, new DataflowLinkOptions { PropagateCompletion = true }); delayer.LinkTo(sender, new DataflowLinkOptions { PropagateCompletion = true }); items.Add(new Item { Com = communication, CancelletionSource = cancellationTokenSource }); try { State = SendingState.Sending; communication.State = SendingState.Sending; communication.StartSendingTime = DateTime.Now; OnSendingStarted(communication); while (communication.DataSource.Read()) mapper.Post(communication.DataSource.Row); mapper.Complete(); sender.Completion.Wait(); OnSendingCompleted(communication); communication.State = SendingState.Stopped; } catch (AggregateException ex) { communication.State = SendingState.Cancelled; OnSendingCancelled(communication, ex.InnerException); } catch (Exception ex) { communication.State = SendingState.Cancelled; OnSendingCancelled(communication, ex); } finally { items.RemoveAll(i => i.Com == communication); State = SendingState.Stopped; } }, null, TaskCreationOptions.PreferFairness); }
public static void StopCommunication(MaillingCommunication communication) { Contract.Requires(communication != null); try { items.Single(i => i.Com == communication).CancelletionSource.Cancel(); communication.State = SendingState.Cancelled; OnSendingCancelled(communication, new Exception("User cancelled the sending.")); } catch { throw new Exception("Specified communication was not found in the SendPool."); } }