Ejemplo n.º 1
0
        /// <summary>
        /// Send a message to the Receivers. This is (partly) a blocking function.
        /// </summary>
        /// <param name="message">
        /// If the given object is a byte array, it will not be serialized. Otherwise, the object will be serialized using a binary formatter.
        /// </param>
        public void Send(object message)
        {
            lock (_lock)
                try {
                    if (!IsDisposed)
                    {
                        SetTcpSenders();

                        BeforeMessageSent?.Invoke(this, new MessageEventArgs()
                        {
                            Handle = Handle, Message = message, RemoteEndPoints = _tcpSenders.Values.ToArray()
                        });

                        if (_tcpSenders.Count != 0)
                        {
                            if (Buffered)
                            {
                                if (message.GetHashCode() != _hashcode)
                                {
                                    _bytes    = SerializeMessage(message);
                                    _hashcode = message.GetHashCode();
                                }
                                Parallel.ForEach(_tcpSenders, (kvp) => Send(kvp.Key, kvp.Value, _bytes));
                            }
                            else
                            {
                                Parallel.ForEach(_tcpSenders, (kvp) => Send(kvp.Key, kvp.Value, SerializeMessage(message)));
                            }
                        }

                        AfterMessageSent?.Invoke(this, new MessageEventArgs()
                        {
                            Handle = Handle, Message = message, RemoteEndPoints = _tcpSenders.Values.ToArray()
                        });
                    }
                }
                catch (Exception ex) {
                    if (!IsDisposed && OnSendFailed != null)
                    {
                        OnSendFailed(this, new ErrorEventArgs(ex));
                    }
                }
        }
Ejemplo n.º 2
0
        /// <inheritdoc cref="IMailClient.SendAsync(IMessageBuilder, IDataRecord, IEnumerable{IMessageMutator}, CancellationToken)"/>
        protected virtual async Task <(MimeMessage?Message, bool Stop)> SendAsyncImpl(IMessageBuilder messageBuilder, IDataRecord record, IEnumerable <IMessageMutator> messageMutators, IFormatProvider formatProvider, int index, int count, CancellationToken cancellationToken)
        {
            IMessageBuilder message = messageBuilder.Clone();

            FormatMessage(message, record, formatProvider);
            foreach (IMessageMutator mutator in messageMutators)
            {
                try
                {
                    message = mutator.Mutate(message, record);
                }
                catch (Exception e)
                {
                    MessageMutationErrorEventArgs errorArgs = new MessageMutationErrorEventArgs(message, mutator, e);
                    MessageMutationError?.Invoke(this, errorArgs);
                    if (errorArgs.Stop)
                    {
                        return(null, true);
                    }
                    else if (errorArgs.Skip)
                    {
                        MessageProcessed?.Invoke(this, new MessageProcessedEventArgs(message.ToMessage(), index, count, ProcessedType.Skipped));
                        return(null, false);
                    }
                    else if (errorArgs.SkipMutation)
                    {
                        continue;
                    }
                    throw;
                }
            }

            BeforeMessageSentEventArgs beforeArgs = new BeforeMessageSentEventArgs(message);

            BeforeMessageSent?.Invoke(this, beforeArgs);
            if (beforeArgs.Stop)
            {
                return(null, true);
            }
            else if (beforeArgs.Skip)
            {
                MessageProcessed?.Invoke(this, new MessageProcessedEventArgs(message.ToMessage(), index, count, ProcessedType.Skipped));
                return(null, false);
            }

            MimeMessage result  = message.ToMessage();
            int         attempt = 0;

            while (true)
            {
                try
                {
                    ITransferProgress transferProgress = new TransferProgress((bytesTransferred, totalSize) =>
                                                                              MessageTransferProgress?.Invoke(this, new MessageTransferProgressEventArgs(result, bytesTransferred, totalSize)));

                    await Client.SendAsync(result, cancellationToken, progress : transferProgress).ConfigureAwait(false);

                    MessageSent?.Invoke(this, new MessageSentEventArgs(result));
                    MessageProcessed?.Invoke(this, new MessageProcessedEventArgs(result, index, count, ProcessedType.Sent));
                    return(result, false);
                }
                catch (Exception e)
                {
                    MessageTransferErrorEventArgs errorArgs = new MessageTransferErrorEventArgs(result, e, ++attempt);
                    MessageTransferError?.Invoke(this, errorArgs);
                    if (errorArgs.Stop)
                    {
                        return(null, true);
                    }
                    else if (errorArgs.Skip)
                    {
                        MessageProcessed?.Invoke(this, new MessageProcessedEventArgs(result, index, count, ProcessedType.Skipped));
                        return(null, false);
                    }
                    else if (errorArgs.Retry)
                    {
                        continue;
                    }
                    throw;
                }
            }
        }