Imap IDLE
IDLE is an IMAP feature described in RFC 2177 that allows a client to indicate to the server that it is ready to accept real-time notifications.
IMAP4 servers that support IDLE will include this programming string in the result of their CAPABILITY command.
You can use SupportedExtensionsmethod to check server’s capability list
// C# code
using (Imap client = new Imap())
{
client.ConnectSSL("imap.server.com");
foreach (ImapExtension extension in client.SupportedExtensions())
{
Console.WriteLine(extension.Name);
}
bool supportsIdle = client.SupportedExtensions()
.Contains(ImapExtension.Idle);
client.Close();
}
' VB.NET code
Using client As New Imap()
client.ConnectSSL("imap.server.com")
For Each extension As ImapExtension In client.SupportedExtensions()
Console.WriteLine(extension.Name)
Next
Dim supportsIdle As Boolean = client.SupportedExtensions() _
.Contains(ImapExtension.Idle)
client.Close()
End Using

Mail.dll IMAP client supports IDLE command.
There are two important methods:
- Idle() – starts accepting real-time notifications. The method hangs until a notification is received.
- StopIdle() – stops accepting real-time notifications.
// C# code
using (Imap client = new Imap())
{
client.ConnectSSL("imap.server.com");
client.Login("user@server.com", "password");
FolderStatus folderStatus = client.SelectInbox();
Console.WriteLine("Total message count: {0}",
folderStatus.MessageCount);
while(true)
{
FolderStatus currentStatus = client.Idle();
Console.WriteLine("Total message count: {0}",
currentStatus.MessageCount);
foreach(long uid in client.SearchFlag(Flag.Unseen))
{
IMail email = new MailBuilder().CreateFromEml(
client.GetHeadersByUID(uid));
Console.WriteLine(email.Subject);
}
}
client.Close();
}
' VB.NET code
Using client As New Imap()
client.ConnectSSL("imap.server.com")
client.Login("user@server.com", "password")
Dim folderStatus As FolderStatus = client.SelectInbox()
Console.WriteLine("Total message count: {0}",_
folderStatus.MessageCount)
While True
Dim currentStatus As FolderStatus = client.Idle()
Console.WriteLine("Total message count: {0}",_
currentStatus.MessageCount)
For Each uid As Long In client.SearchFlag(Flag.Unseen)
Dim email As IMail = New MailBuilder()_
.CreateFromEml(client.GetHeadersByUID(uid))
Console.WriteLine(email.Subject)
Next
End While
client.Close()
End Using

Now lets handle stop gracefully:
// C# code
using (Imap client = new Imap())
{
client.ConnectSSL("imap.server.com");
client.Login("user@server.com", "password");
FolderStatus folderStatus = client.SelectInbox();
Console.WriteLine("Total message count: {0}",
currentStatus.MessageCount);
bool stop = false;
// We start a new thread to handle user input, <enter> = stop idle
new Thread(() =>
{
Console.ReadLine();
client.StopIdle();
stop = true;
}).Start();
while(stop == false)
{
FolderStatus currentStatus = client.Idle();
if (stop == true)
break;
Console.WriteLine("Total message count: {0}",
currentStatus.MessageCount);
foreach(long uid in client.SearchFlag(Flag.Unseen))
{
IMail email = new MailBuilder().CreateFromEml(
client.GetHeadersByUID(uid));
Console.WriteLine(email.Subject);
}
}
client.Close();
}
' VB.NET code
Using client As New Imap()
client.ConnectSSL("imap.server.com")
client.Login("user@server.com", "password")
Dim folderStatus As FolderStatus = client.SelectInbox()
Console.WriteLine("Total message count: {0}",_
currentStatus.MessageCount)
Dim [stop] As Boolean = False
' We start a new thread to handle user input, <enter> = stop idle
New Thread(Function() Do
Console.ReadLine()
client.StopIdle()
[stop] = True
End Function).Start()
While [stop] = False
Dim currentStatus As FolderStatus = client.Idle()
If [stop] = True Then
Exit While
End If
Console.WriteLine("Total message count: {0}",_
currentStatus.MessageCount)
For Each uid As Long In client.SearchFlag(Flag.Unseen)
Dim email As IMail = New MailBuilder()_
.CreateFromEml(client.GetHeadersByUID(uid))
Console.WriteLine(email.Subject)
Next
End While
client.Close()
End Using

January 8th, 2012 at 01:27
Is there a command where client.SelectInbox() can be replaced so that you can get the all mail folder instead? I figure that would be better so that only one IDLE connection is required for an account. Is there a way to find out which email goes with which folder in this case?
January 8th, 2012 at 21:52
@Scott
You can use any folder name:
client.Select("All Mail")In case of Gmail you may want to use CommonFolders class to get the All Mail folder name:
http://www.lesnikowski.com/blog/localized-gmail-imap-folders
> Is there a way to find out which email goes with which folder in this case?
In case of Gmail you can get all labels for specified message:
http://www.lesnikowski.com/blog/get-gmail-labels-for-specified-messages
January 15th, 2012 at 14:44
[...] use push email [...]