I've created a create a console app that would:
- Call a method to check an email account (I've done this step)
- Convert the attachment to pdf (I've done this step)
- Then once the conversion is complete wait 30 seconds
- Repeat the previous 3 steps continuously
I've done Step 1 and 2 int the ProcessMailMessages() method. The following code works but I want to know if I am on the right track or is there a better way to poll a email client?
private static int secondsToWait = 30 * 1000;
static void Main(string[] args)
{
bool run = true;
do
{
try
{
Task theTask = ProcessEmailTaskAsync();
theTask.Wait();
}
catch (Exception e)
{
Debug.WriteLine("<p>Error in Client</p> <p>Exception</p> <p>" + e.Message + "</p><p>" + e.StackTrace + "</p> ");
}
GC.Collect();
} while (run);
}
static async Task ProcessEmailTaskAsync()
{
var result = await EmailTaskAsync();
}
static async Task<int> EmailTaskAsync()
{
await ProcessMailMessages();
await Task.Delay(secondsToWait);
return 1;
}
static async Task ProcessMailMessages()
{
...............................................................................
}
3 Answers 3
I would rather do smth. like that (I added CancellationToken in case you would want to be able to cancel email parsing while it's in progress):
private static TimeSpan timeToWait = TimeSpan.FromSeconds(30);
//somewhere in your code:
_cancellationTokenSource = new CancellationTokenSource();
private static void Main(string[] args)
{
CancellationToken token = _cancellationTokenSource.Token;
do
{
try
{
ProcessEmailsAndWaitAsync(token).Wait();
}
catch (Exception e)
{
Debug.WriteLine("<p>Error in Client</p> <p>Exception</p> <p>" + e.Message + "</p><p>" + e.StackTrace + "</p> ");
}
} while (!token.IsCancellationRequested);
}
private static async Task ProcessEmailsAndWaitAsync(CancellationToken token)
{
await ProcessMailMessages(token);
await Task.Delay(timeToWait, token);
}
private static async Task ProcessMailMessages(CancellationToken token)
{
//...............................................................................
}
- Calling
GC.Collect()
shouldn't be necessary except in very specific circumstances. Don't do it if you don't have a very good reason. - Why are do you have unused local variable in
ProcessEmailTaskAsync()
? It's not useful for anything. What's more, what is the whole point of the method? You canWait()
onTask<int>
too. - It's not clear what does the
int
returned fromEmailTaskAsync()
mean. If it's supposed to represent status, anenum
would be much better. If you do need to useint
for some reason, you really should document what each value means. And in your case, you always return the same value and it doesn't seem to be used anywhere, so you should just change the return type toTask
and don't return anything. Using
async
-await
won't give you any benefit in your case. Basically, there are two reasons for usingasync
-await
:- It can use smaller number of threads, improving efficiency.
- It can avoid blocking the UI thread, improving responsiveness.
Neither of those reasons is relevant in your case (you don't have a UI thread and using
async
-await
this way will use more threads, not less, because of theWait()
), so you should consider whether usingasync
-await
will give you any benefit at all.
-
\$\begingroup\$ Hi Svick, Thanks for the constructive feedback, Are you able to provide an alternative implementation? \$\endgroup\$user1825645– user18256452012年11月19日 05:50:53 +00:00Commented Nov 19, 2012 at 5:50
-
\$\begingroup\$ Why? Are any of my suggestions unclear? \$\endgroup\$svick– svick2012年11月19日 19:21:25 +00:00Commented Nov 19, 2012 at 19:21
I believe you could use a much more elegant solution using the ContineWith method on the Task object
Here is some basic pseudo code...
function RecursiveEmailPollRoutine()
{
var PollEmailTask = new Task(() => {
//Poll the email
//Pause for your delay
}).ContinueWith(()=> {
//check your cancel var
//and cancel if need be
//otherwise recursively
//call this function
}).Start();
)
This hasn't been tested but you get the gist. I hope this helps.
-
4\$\begingroup\$ Please don't link to your blog in every (or any) answer. Linking to a specific blog post that's relevant to the question is fine as long as you summarize the content of the post in your answer, but just linking to your blog without any indication of how it's relevant to the question is against the rules. \$\endgroup\$sepp2k– sepp2k2012年11月15日 18:12:17 +00:00Commented Nov 15, 2012 at 18:12
-
2\$\begingroup\$ Are you seriously saying this code is more readable than using
async
-await
? The whole point of that is to avoid code like this. Besides, your code won't work, because you can'tStart()
theTask
returned fromContinueWith()
. On the other hand, you have toStart()
theTask
if you create it directly using an constructor. \$\endgroup\$svick– svick2012年11月17日 10:54:24 +00:00Commented Nov 17, 2012 at 10:54
CG.Collect();
? \$\endgroup\$