SendEmailAsync benefits doubtful - c#

I read this on MSDN documentation, which seems to imply that I will still need to wait after calling the SendAsync method in my code, which is pasted below. Is this right? If it is, then I might as well just use the synchronous method of Send rather than SendAsync. My goal was to go to the next email message in my loop and send it without waiting for the previous one to be sent, which would allow me to handle the emailMessages collection more quickly as compared to using Send method. But it doesn't seem true.
After calling SendAsync, you must wait for the e-mail transmission to complete before attempting to send another e-mail message using Send or SendAsync.
I am using C# and .Net framework 4.5. In my code, I am trying to send multiple emails from within a loop as in code below using SendAsync method.
List<EmailMessage> emailMessages = DAL.GetEmailsToBeSent();
SmtpClient client = new SmtpClient();
foreach(EmailMessage emailMessage in emailMessages)
{
//create a message object from emailMessage object and then send it asynchronously
client.SendAsync(message);
//client.Send(message);
}

The advantage of the async method over the non-async alternative is that you don't need to block the current thread. This is particularly helpful in UI environments where you don't want to be blocking the UI thread, and also prevents the need for blocking a thread pool thread.
If you're just going to do a blocking wait on the results, it has no advantage over the non-async alternative.

Related

Calling ServiceBus' IQueueClient.CompleteAsync() from a different thread always fails

I'm receiving from a queue using IQueueClient.RegisterMessageHandler(), and in the receiving method I'm then starting a Hangfire task. But in the Hangfire task, all calls to IQueueClient.CompleteAsync() to mark the message as consumed (because I'm using ReceiveMode.PeekLock mode) fail.
I suspect it's because the Hangfire task re-creates the IQueueClient, that it may be because the call to CompleteAsync() is from a different instance of IQueueClient? Or is something else possibly going wrong? I'm passing Message.SystemProperties.LockToken into the Hangfire task which is what is then being used by CompleteAsync.
I suspect it's because the Hangfire task re-creates the IQueueClient, that it may be because the call to CompleteAsync() is from a different instance of IQueueClient?
That's correct. LockToken is not enough to complete the message. You have to use the same client used to receive the message in order to complete it.

Asynchronous error on SmtpClient SendMailAsync in http handler (ashx)

I've been running a C# http handler (ashx) to send mail for years. We believe the problem started when we switched to 4.5.1. We are getting the error:
"An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle..."
I was using:
public static void sendMessage(....
...
client.SendAsync(message);
After looking around for what was happening, the method was changed to:
public static async Task sendMessage(....
...
await client.SendMailAsync(message);
I'm assuming that we still get this error because not all the calls up the stack have the async operator. To do that, I'd have to make the entire handler, that does many other things, asynchronous which doesn't sound like a good idea just to send mail.
So, I have two questions:
Am I correct in that I'm not using async in every method that eventually calls sendMessage?
How do I send mail asynchronously now?
Since there were no more comments, I just started a new thread and sent the message synchronously. Seems to work fine, haven't had a problem since.

Wait for server before receiving stream

I'm trying to implement a client-server socket system based on this MSDN article and I have it working. If I do this it works fine when the server is returning a string immediately.
client.send();
client.receive();
The problem is if my send method requests something that takes the server a few minutes to process, such as creating a PDF version of a file, the receive call executes straight after and receives nothing (because the server hasn't sent anything as it's still processing the PDF).
How can I make the client wait for a certain period of time before executing the receive method so that it's called once the server has finished processing and has sent the file?
This seems to be the difference between a blocking and non-blocking receive call. A blocking receive call would wait until it actually had something to receive or it would timeout. A non-blocking receive call would return right away whether data is present or not. I don't know what call this is but I know C# has both types of calls.
The link you gave was to a asynchronous socket example which is generally different than what you are trying to do. What you are trying to do is more similar to a synchronous style.
Asynchronous in terms of sockets usually means you would register a function to be called when data was received. Synchronous means to poll (explicitly ask for data) in either a blocking or non-blocking manner.
EDIT:
You would send your data and set a class variable saying you have sent something and are expecting to receive something. Then wait for that variable to be cleared saying you've received something.
sent = 1
client.send()
while(sent);
Then in your receive callback when you actually get something you would set that variable.
/* receive data and process */
sent = 0;
Use async and wait. The function will get called after the call returns.
http://msdn.microsoft.com/en-us/library/vstudio/hh156513.aspx

Creating an async/await API wrapping a request/response protocol

I have a request/response protocol that runs over TCP that I'd like to provide an async/await API for. The protocol is STOMP, which is a fairly simple text-based protocol that runs over TCP or SSL. In STOMP, the client sends one of six or so command frames and specifies a receipt ID in the header of the command. The server will respond with either a RECEIPT or ERROR frame, with a receipt-id field, so the client can match the response with the original request. The server can also send a MESSAGE frame at any time (STOMP is fundamentally a messaging protocol) which will not contain a receipt-id.
To allow multiple outstanding requests and handle any MESSAGE frames, the plan is to always have a Socket.BeginReceive() outstanding. So what I was thinking is that the easiest implementation would be to create a waitable event (like a mutex), store that event in a table, send the command request with the receipt set to the index into the table, and block on the event. When socket.BeginReceive() fires the function can get the receipt-id from the message, look up the event in the table, and signal it (and store some state, like success or error). This will wake up the calling function, which can look at the result and return success or failure to the calling application.
Does this sound fundamentally correct? I've used async/await APIs before but have never written my own. If it's OK what kind of waitable event should I use? A simple Monitor.Wait() will block but not in the way I want, correct? If I wrap the whole thing in Task.Run() will that behave properly with Monitor.Wait()? Or is there a new synchronization construct that I should be using instead? I'm basically implementing HttpClient.GetAsync(), does anyone know how that works under the covers?
HttpClient is much simpler, because HTTP only has one response for each request. There's no such thing as an unsolicited server message in HTTP.
To properly set up a "stream" of events like this, it's best to use TPL Dataflow or Rx. Otherwise, you'd have to create an unbounded receive buffer and have repeated async ReceiveMessage calls.
So I'd recommend using a TPL Dataflow pipeline to create a source block of "messages", and then matching some up with requests (using TaskCompletionSource to notify the sender it's complete) and exposing the rest (MESSAGE frames) as a source block.
Internally, your processing pipeline would look like this:
Repeated BeginReceive ->
TransformBlock for message framing ->
ActionBlock to match response messages to requests.
BufferBlock for MESSAGE frames.

Does it makes sense to queue send operations when using Socket.SendAsync?

I am using .NET async send method (SendAsync) from Socket class. Do I need to queue send operations in order to send the payload over the wire one by one after the previous transmission finishes?
I've noticed that SendAsync will accept happily any bytes I throw at it without complaining that the previous send has finished or not. The protocol I am using deals with out-of-order messages.
Does the Windows socket stack already do queuing internally?
The Socket-class should do this internaly - if you check the return value HERE:
Returns true if the I/O operation is pending.
Returns false if the I/O operation completed synchronously.

Categories

Resources