Avoid recursive event in c# - c#

Hi I 've a little question,
I'm using socket and I find many situation of infinite recursion see source: http://pastebin.com/Cbd2Z2uE
the problem is this:
private static void ReceiveCallback(IAsyncResult ar)
{
....
// receive again
socket.BeginReceive(state.Buffer,
0,
StateObject.BufferSize,
0,
ReceiveCallback,
state);
....
}
So we have an async function that is called again in a recursive way. Here We have a problem with the stack?
To be more clear, this situation is ok and recursion is fine, the problem and question is:
in this case can I have a problem of stackoverflow?
thanks

You are not recursing (or in danger or recursing). You are simply scheduling a callback to be executed when an IO competion port receives data for you to process (checked source code to see this). This will not happen while your function is running on the current thread because the very same thread has to check for message on IO port via polling or another worker thread will run your function all together. In either case you are not recursing or in danger of recusing so the stack will not blow up (socket.BeginReceive should return immediatly & will not call your function in it).
I believe you are looking at scenario 14 shown on this page but it may be the previous scenario since your console app has a message pump. But the bottom line is that there is no actual functions recursing in your application (or supporitng OS framework functionality used by it).

Your ReceiveCallback is called by framework code unless you call it directly.
BeginReceive stores specified delegate as callback function, and it doesn't calls the delegate at that time.
For example, I added some codes to get stack trace:
private static void ReceiveCallback(IAsyncResult ar)
{
Console.WriteLine(Environment.StackTrace);
// retrieve the state and socket
and gets:
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at Program.ReceiveCallback(IAsyncResult ar) in r:\Temp\LINQPad\aqwfvqfb\query_ettlka.cs:line 102
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
And It's shown even you call BeginReceive in ReceiveCallback.

Related

ObjectDisposedException SslStream and TcpClient

I am using a TcpClient with an SslStream. In general everything works fine but we are getting occasional logs of crashes. It seems to be coming from unstable network connections, and I'm unfortunately not able to reproduce it locally despite trying to create "unexpected circumstances":
using Fiddler to replicate a very slow network connection
killing the server application while its sending data
disconnecting network cables
The situation is this:
I call BeginRead like this:
_tcpClientStream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, pfnCallBack, null);
And then EndRead is being called like this:
iRx = _tcpClientStream.EndRead(asyn);
The only place that the iRx is used is to copy the received data to a new array:
var bytes = new byte[iRx];
Array.Copy(receiveBuffer, bytes, iRx);
In the OnDataReceived callback function, I call EndRead on the SslStream, which throws an exception that is handled:
Error in OnDataReceived System.IO.IOException: The read operation failed, see inner exception. ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: size
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.FixedSizeReader.StartReading()
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
--- End of inner exception stack trace ---
at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult)
at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult)
at XXXXXXX.OnDataRecevied(IAsyncResult asyn)
Normally this is not a problem - this exception is caught and the TcpClient is closed and re-initiated to attempt to reconnect.
However, in this case there is a second Exception that is thrown and comes from one of the UnhandledException error handlers:
AppDomain.CurrentDomain.UnhandledException
Current.DispatcherUnhandledException
Current.Dispatcher.UnhandledException
TaskScheduler.UnobservedTaskException
This stack trace is like this:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Our handling for this type of unhandled error is to display a message to the user that there is a fatal error and the software has to close.
My questions are:
Has anyone ever seen this error before and been able to reproduce the exact out of range exception I'm getting? Despite my attempts to recreate the issue (using the methods described above), I'm not able to ever recreate the exception, it is always the more standard Socket IO exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult)
at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult)
at XXXXXXXXX.OnDataRecevied(IAsyncResult asyn)
Is there any way I can handle this exception in my Socket code or is it always going to appear in one of these UnhandledException events? If so, what is the best practice way of handling this? Basically I need some logic in the event handler to identify that the software should not shut down if this specific error is received?

Transport agent cannot find a certificate in local store

The error is as following:
The transport process failed during message processing with the following call stack: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Cannot find the X.509 certificate using the following search criteria: StoreName 'My', StoreLocation 'CurrentUser', FindType 'FindByThumbprint', FindValue 'c454f0a61e4cb0ed77ae87ede892ff09e584eca2'.
at System.ServiceModel.Security.SecurityUtils.GetCertificateFromStoreCore(StoreName storeName, StoreLocation storeLocation, X509FindType findType, Object findValue, EndpointAddress target, Boolean throwIfMultipleOrNoMatch)
at System.ServiceModel.Security.SecurityUtils.GetCertificateFromStore(StoreName storeName, StoreLocation storeLocation, X509FindType findType, Object findValue, EndpointAddress target)
at System.ServiceModel.Security.X509CertificateInitiatorClientCredential.SetCertificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, Object findValue)
at Zeva.WCFHelper.ClientBaseWrapper`1..ctor(BindingSettings bindingSettings, String address, String spnIdentity, Maybe`1 certificateAuthenticationSettings)
--- End of inner exception stack trace ---
at SampleCompany.TransportAgent.ModificationAgent.OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs eodArgs) in C:\Users\rani\Source\Workspaces\Mobility\Dev\SampleCompany\SampleCompany.TransportAgent\ModificationAgent.cs:line 48
at Microsoft.Exchange.Data.Transport.Smtp.SmtpReceiveAgent.Invoke(String eventTopic, Object source, Object e)
at Microsoft.Exchange.Data.Transport.Internal.MExRuntime.Dispatcher.Invoke(MExSession session)
at Microsoft.Exchange.Data.Transport.Internal.MExRuntime.MExSession.AsyncInvoke(Object state)
at Microsoft.Exchange.Data.Transport.Internal.MExRuntime.MExSession.BeginInvoke(String topic, Object source, Object e, AsyncCallback callback, Object callbackState)
at Microsoft.Exchange.Protocols.Smtp.BaseDataSmtpCommand.RaiseEODEvent(Object state)
at Microsoft.Exchange.Protocols.Smtp.BaseDataSmtpCommand.OnEod(Boolean isAsync)
at Microsoft.Exchange.Protocols.Smtp.BaseDataSmtpCommand.RawDataReceived(Byte[] data, Int32 offset, Int32 numBytes)
at Microsoft.Exchange.Protocols.Smtp.SmtpInSession.ReadComplete(IAsyncResult asyncResult)
at Microsoft.Exchange.Net.LazyAsyncResult.WorkerThreadComplete(Object state)
at Microsoft.Exchange.Net.LazyAsyncResult.Complete(IntPtr userToken)
at Microsoft.Exchange.Net.LazyAsyncResult.ProtectedInvokeCallback(Object value, IntPtr userToken)
at Microsoft.Exchange.Net.NetworkConnection.InvokeRecvCallback(LazyAsyncResultWithTimeout asyncResult, Object result)
at Microsoft.Exchange.Net.NetworkConnection.ReadDataAvailable(IAsyncResult asyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Description:
I am implementing a transport agent that do some modification emails, it is required that I call a WCF service that returns some data and based on that data I do the modification.
the issue arises when calling the WCF service (which is very well tested and in use for production). apparently, the transport agent cannot find the certificates in the current user store.
What I have already tried:
1. install the certificate (pfx file) into current user account (logically this should not work as the current user for transport agent is Network service).
2. install for the local machine, also did not work.
3. install for the service account (Microsoft Exchange Transport), also did not find the certificate.
So my question is how to install certificates to be used by code within transport agents?

Try catch async await https exception

I have what seems a really weird situation. I have some async/await code which uses RestSharp to get some data off several rest APIs (same API hosted on different URLs) which a kind of directory service returns.
Now the problem: one of the APIs returned by said directory service is somehow "private" and initiating a SSL connection to it fails. Fiddler captures the following response:
HTTP/1.1 200 Connection Established
FiddlerGateway: Direct
StartTime: 19:13:11.117
Connection: close
fiddler.network.https> HTTPS handshake to foo.bar.com failed. System.IO.IOException The handshake failed due to an unexpected packet format.
I would ideally like to skip getting data from this API in case this happens and just move on. However, it turns out that a try/catch doesn't help! A NullReferenceException is thrown but even a generic try/catch doesn't manage to catch it.
The code is pretty straightforward:
try
{
await GetDataAsync(url);
}
catch
{
// never gets called
}
and
private async Task<List<Data>> GetDataAsync(string url)
{
var request = new RestRequest("/foo");
var restClient = new RestClient(url);
var response = await restClient.ExecuteTaskAsync<List<Data>>(request); // <-- this throws
return response.Data;
}
I've extracted the code in a library and tried it both in a Console app and in a WPF app, same result, catch block never gets entered.
Any ideas?
l.e.: as requested, here's the full exception stack trace
Unhandled Exception: System.NullReferenceException: Object reference not set to
an instance of an object.
at RestSharp.RestClient.<>c__DisplayClass15`1.<ExecuteTaskAsync>b__12(IRestResponse`1 response, RestRequestAsyncHandle _)
at RestSharp.RestClient.DeserializeResponse[T](IRestRequest request, Action`2 callback, IRestResponse response, RestRequestAsyncHandle asyncHandle)
at RestSharp.RestClient.<>c__DisplayClassa`1.<ExecuteAsync>b__9(IRestResponse response, RestRequestAsyncHandle asyncHandle)
at RestSharp.RestClient.ProcessResponse(IRestRequest request, HttpResponse httpResponse, RestRequestAsyncHandle asyncHandle, Action`2 callback)
at RestSharp.RestClient.<>c__DisplayClass3.<ExecuteAsync>b__0(HttpResponse r)
at RestSharp.Http.ExecuteCallback(HttpResponse response, Action`1 callback)
at RestSharp.Http.ResponseCallback(IAsyncResult result, Action`1 callback)
at RestSharp.Http.<>c__DisplayClass3.<GetStyleMethodInternalAsync>b__1(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.HttpWebRequest.SetResponse(Exception E)
at System.Net.HttpWebRequest.CheckWriteSideResponseProcessing()
at System.Net.ConnectStream.ProcessWriteCallDone(ConnectionReturnResult returnResult)
at System.Net.HttpWebRequest.WriteCallDone(ConnectStream stream, ConnectionReturnResult returnResult)
at System.Net.ConnectStream.CallDone(ConnectionReturnResult returnResult)
at System.Net.ConnectStream.IOError(Exception exception, Boolean willThrow)
at System.Net.ConnectStream.HandleWriteHeadersException(Exception e, WebExceptionStatus error)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.TlsStream.ResumeIOWorker(Object result)
at System.Net.TlsStream.WakeupPendingIO(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Security.SslState.FinishHandshake(Exception e, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result)
at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
This seems to be a bug in RestSharp. I'm not sure you can do anything about it without modifying RestSharp's source.

Log4net randomly stops logging

I get the following message in the eventlog for my service:
Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.
StackTrace:
at log4net.Appender.RollingFileAppender.AdjustFileBeforeAppend() in C:\Projects\Framework\log4net-1.2.11\src\Appender\RollingFileAppender.cs:line 609
at log4net.Appender.RollingFileAppender.Append(LoggingEvent loggingEvent) in C:\Projects\Framework\log4net-1.2.11\src\Appender\RollingFileAppender.cs:line 562
at LSports.Common.Logger.Appenders.AsynchronousFileAppender.LogMessages() in d:\tfsV3\Dev\Common\Logger\LSports.Common.Logger\Appenders\AsynchronousFileAppender .cs:line 63
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
I use the log4net in more projects in the system beside the webservice and it just getting randomly stuck there too.
I looked in source file of log4net where the exception occurs and it happens when it tries to perform file rolling
if (m_rollSize)
{
/* this line*/ if ((File != null) && ((CountingQuietTextWriter)QuietWriter).Count >= m_maxFileSize)
{
RollOverSize();
}
}
what could be causing this? it just happens totally random
After a lot of searching i finally found the problem, the log4net actually hangs because it tries to print error to console, and my application is hidden so it fails to print to the console and just stops the thread that called the log4net.

Is there a limit to the number of tasks?

I am running a winrt program with multiple tasks.
In the middle of running, I get the following exception:
Not enough quota is available to process this command
The stack trace is
at Windows.UI.Core.CoreDispatcher.InvokeAsync(CoreDispatcherPriority priority, InvokedHandler freeThreadedCallback, Object sender, Object context)
at System.Threading.WinRTSynchronizationContext.Post(SendOrPostCallback d, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.InvokeOrPostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunInline(ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<ThrowAsyncIfNecessary>b__1(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
Then it crashes.
Is this a problem specific to WintRT?
Is there a workaround?
According to the MSDN documentation for that error message, the fix for that error is to either "close some applications" or "increase the size of your paging file".
Given that, you might want to start by looking in Task Manager and see if your application is using a totally unreasonable amount of memory (or if some other process is). If your process has a memory leak, it might lead to this problem.

Categories

Resources