While I'm developing an application based on Idle mechanics, I'm facing a strange behaviour.
Once the message arrives through the handler OnNewMessage, when I try to __Move__, __Copy__ of even __Flag__ the message, __I sometimes get a NotSupportedException__ !
Since the application is multithreaded, __I tried to put a lock section around the call to MoveTo__, __No way__ I still get the bloody exception.
I'm running this through a Unit Test, the one is waiting for new message while it also send mail by the way of an SMTP client to the mailbox. May there is a clue here !
Here is an excerpt of the Stack Trace below:
```
An exception of type 'System.NotSupportedException' occurred and was caught.
----------------------------------------------------------------------------
05/30/2016 21:48:59
Type : System.NotSupportedException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Impossible d'appeler la méthode Read lorsqu'une autre opération read est en attente.
Source : System
Help link :
Data : System.Collections.ListDictionaryInternal
TargetSite : Int32 ProcessRead(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)
HResult : -2146233067
Stack Trace : Ã System.Net.Security._SslStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
à System.Net.Security.SslStream.Read(Byte[] buffer, Int32 offset, Int32 count)
à System.IO.StreamReader.ReadBuffer()
à System.IO.StreamReader.ReadLine()
à ImapX.ImapBase.SendAndReceive(String command, IList`1& data, CommandProcessor processor, Encoding encoding, Boolean pushResultToDatadespiteProcessor)
à ImapX.Folder.Select()
à ImapX.Message.CopyTo(Folder folder, Boolean downloadCopy)
à ImapX.Message.MoveTo(Folder folder, Boolean downloadCopy)
```
By Inspecting the Threads, I can notice a concurrency between this two ones, asa I call 'MoveTo':
```
Worker Thread <No Name> System.dll!System.Net.Security._SslStream.ProcessWrite Normal
System.dll!System.Net.Security._SslStream.ProcessWrite(byte[] buffer = {byte[6]}, int offset = 0, int count = 6, System.Net.AsyncProtocolRequest asyncRequest = null)
System.dll!System.Net.Security._SslStream.Write(byte[] buffer = {byte[6]}, int offset = 0, int count = 6)
System.dll!System.Net.Security.SslStream.Write(byte[] buffer = {byte[6]}, int offset = 0, int count = 6)
ImapX.dll!ImapX.ImapBase.StopIdling(bool pausing = true)
ImapX.dll!ImapX.ImapBase.PauseIdling()
ImapX.dll!ImapX.ImapBase.SendAndReceive(string command = "UID FETCH 2222 (FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS (FROM TO DATE SUBJECT CC CONTENT-TYPE)] BODYSTRUCTURE X-GM-MSGID X-GM-THRID X-GM-LABELS)", ref System.Collections.Generic.IList<string> data = Count = 0, ImapX.Parsing.CommandProcessor processor = null, System.Text.Encoding encoding = null, bool pushResultToDatadespiteProcessor = false)
ImapX.dll!ImapX.Message.Download(ImapX.Enums.MessageFetchMode mode = Basic | GMailExtendedData, bool reloadHeaders = false)
ImapX.dll!ImapX.Folder.Fetch(System.Collections.Generic.IEnumerable<long> uIds = {long[8]}, ImapX.Enums.MessageFetchMode mode = -1)
ImapX.dll!ImapX.Folder.Search(string query = "UID 2215:2222", ImapX.Enums.MessageFetchMode mode = -1, int count = -1)
ImapX.dll!ImapX.ImapBase.ProcessIdleServerEvents()
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
[Native to Managed Transition]
Worker Thread <No Name> System.dll!System.Net.Security._SslStream.ProcessRead Normal
System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer = {byte[1]}, int offset = 0, int count = 1, System.Net.AsyncProtocolRequest asyncRequest = null)
System.dll!System.Net.Security._SslStream.Read(byte[] buffer = {byte[1]}, int offset = 0, int count = 1)
System.dll!System.Net.Security.SslStream.Read(byte[] buffer = {byte[1]}, int offset = 0, int count = 1)
mscorlib.dll!System.IO.Stream.ReadByte()
ImapX.dll!ImapX.ImapBase.WaitForIdleServerEvents()
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
[Native to Managed Transition]
```
Thank you for your help!
Comments: ** Comment from web user: sliver **
Hi There,
As far as I understand by debugging the code, the ImapX has the right lock() to make it thread safe, __the problems comes from Highly Threaded application that both send messages in one end and receive messages (from Idle mode) in the other end !__
__Both uses _SslStream.Read of _SslStream?Write and the SSL Stream is not thread safe by nature.__
So, except a __named Mutex to protect the shared ssl resource__ against the running process , I don't see how to resolve this.
___The fix could be to replace the lock(...) of the ImapBase.SendAndReceive method by a process wide named Mutex. To avoid collision.___
Thing is, that if an external client don't release the Mutex, ImapX should be resilient to that, so a timeout could be imagined.
What's your mind ?