C# Async File Download throws System.IO Exception [duplicate] - c#

The following code throws a IOException with the message: "The specified registry key does not exist."
HttpClient client = new HttpClient();
Uri uri = new Uri("http://www.google.com");
client.GetAsync(uri);
This is just in a console app in Main. It looks like the error is being thrown by mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str). I have no idea why this error is being thrown or how to start debugging it.
Edit stack trace:
at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)
It's just 1 line and there is no inner exxception etc..
The call stack is:
mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) + 0x189 bytes
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(string name) + 0x7f bytes
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings() + 0x9e bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy proxy, bool useRegistry) + 0xd0 bytes
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry() + 0x2c bytes
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection section) + 0x1d8 bytes
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection() + 0xec bytes
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get() + 0xcc bytes
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, System.Net.ServicePoint servicePoint) + 0xdf bytes
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, bool returnResponseOnFailureStatusCode, string connectionGroupName, System.Action<System.IO.Stream> resendRequestContent) + 0x2b bytes
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage request) + 0x59 bytes
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0xf4 bytes
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0x4f bytes
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) + 0x13e bytes
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) + 0xc bytes
ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(string[] args) Line 20 + 0x17 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x5a bytes
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes
[Native to Managed Transition]

It seems that this is caused by a recent security update for the .NET Framework: MS12-074: Vulnerabilities in .NET Framework could allow remote code execution: November 13, 2012 (KB 2745030)
It all boils down to the following code in the web proxy resolution:
[RegistryPermission(SecurityAction.Assert, Read=#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework")]
private static void InitializeFallbackSettings()
{
allowFallback = false;
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\.NETFramework"))
{
try
{
if (key.GetValueKind("LegacyWPADSupport") == RegistryValueKind.DWord)
{
allowFallback = ((int) key.GetValue("LegacyWPADSupport")) == 1;
}
}
catch (UnauthorizedAccessException)
{
}
catch (IOException)
{
}
}
}
catch (SecurityException)
{
}
catch (ObjectDisposedException)
{
}
}
As you can see it checks for a specific registry key mentioned in the KB article. Also you should note that the exception is caught internally, but you see it because you have enabled First Chance Exceptions in the debug options of Visual Studio.
If you want to not see this exception you should add the specified registry key with value 0:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
and for 32-bit processes on 64-bit machines:
Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0

I agree with Ligaz's answer, and I've logged a Connect issue about this bug: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details
Save the following into a .reg file and import it into the registry to prevent this error from being raised:
Windows Registry Editor Version 5.00
; The following value prevents an IOException from being thrown and caught
; by System.Net.HybridWebProxyFinder.InitializeFallbackSettings() (in System.dll)
; when WebRequest.Create is first called. By default the "LegacyWPADSupport"
; value doesn't exist, and when InitializeFallbackSettings calls GetValueKind,
; an IOException is thrown. This adds the value with its default of false to
; prevent the exception.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000

For whatever reason, your HttpClient code is looking for proxy settings in the registry and cannot open the key. A look through the code shows that it attempts to open HKCU and then go to one of the following keys in order:
"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
"HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
One of these three is potentially the key your process has no access to, why I am not sure. One possible fix is to disable Automatically Detect Proxy Settings.
Otherwise, you'll need to figure out exactly what key it is loading and we'll do that with two steps.
Enable System.Net logging.
Download and run Procmon, filtering on registry access for your application, like so:
Once opened, disable capturing if enabled (the magnifying glass should have a red X through it).
Start filtering on your processes name.
Unselect all options except Registry Entries
Enable capturing (click the magnifying glass)
Run your application
Find the offending entry in the log, double click to see which key it was opening
Once you determine the offending key, you can work to figure out why your application does not have access to it. Perhaps, if the name of your application is any indication, the user account your service is running under lacks access to the registry key.

Related

C# SQL Server CLR Request error on functions GET and POST

I followed the GitHub documentation to implement the http requests with the CURL extension, work in SQL Server 2008 R2, Visual Studio 2010 and .NET 3.5.
I managed to compile and sign correctly the .dll in visual studio, to then create the schemas and functions in SQL Server, since everything works correctly, I can perform GET and POST from SQL Server, however, when wanting to perform a GET or a POST at SABA API, it generates a series of errors.
A .NET Framework error occurred during execution of user-defined
routine or aggregate "XGET": System.Net.WebException: The underlying
connection was closed: An unexpected error occurred on a send. --->
System.IO.IOException: Received an unexpected EOF or 0 bytes from the
transport stream. System.IO.IOException: at
System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset,
Int32 count) at System.Net.Security.SslState.StartReadFrame(Byte[]
buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer,
AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.CheckCompletionBeforatextReceive(ProtocolTokat
message, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.StartSatdBlob(Byte[] incoming, Int32
count, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.ForceAuthattication(Boolean receiveFirst,
Byte[] buffer, AsyncProtocolRequest asyncRequest) at
System.Net.Security.SslState.ProcessAuthattication(LazyAsyncResult
lazyResult) at
System.Net.TlsStream.CallProcessAuthattication(Object state) at
System.Threading.ExecutionContext.runTryCode(Object userData) at
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode
code, CleanupCode backoutCode, Object userData) at
System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state) at
System.Net.TlsStream.ProcessAuthattication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32
size) at System.Net.ConnectStream.WriteHeaders(Boo ...
System.Net.WebException: at
System.Net.WebCliatt.DownloadDataInternal(Uri address, WebRequest&
request) at System.Net.WebCliatt.DownloadString(Uri address) ...
This is the code of the Assembly
using Microsoft.SqlServer.Server;
using System;
using System.Data.SqlTypes;
using System.Net;
using System.Threading;
public static class Curl
{
[SqlFunction]
[return: SqlFacet(MaxSize = -1)]
public static SqlChars Get(SqlChars H, SqlChars url)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;
var client = new WebClient();
AddHeader(H, client);
return new SqlChars(
client.DownloadString(
Uri.EscapeUriString(url.ToSqlString().Value)
).ToCharArray());
}
[SqlProcedure]
public static void Post(SqlChars H, SqlChars d, SqlChars url)
{
var client = new WebClient();
AddHeader(H, client);
if (d.IsNull)
throw new ArgumentException("You must specify data that will be sent to the endpoint", "#d");
var response =
client.UploadString(
Uri.EscapeUriString(url.ToSqlString().Value),
d.ToSqlString().Value
);
SqlContext.Pipe.Send("Request is executed. " + response);
}
[SqlProcedure]
public static void PostWithRetry(SqlChars H, SqlChars d, SqlChars url)
{
var client = new WebClient();
AddHeader(H, client);
if (d.IsNull)
throw new ArgumentException("You must specify data that will be sent to the endpoint", "#d");
int i = RETRY_COUNT;
string response = "";
do try
{
response =
client.UploadString(
Uri.EscapeUriString(url.ToSqlString().Value),
d.ToSqlString().Value
);
i = -1;
break;
}
catch (Exception ex)
{
SqlContext.Pipe.Send("Error:\t" + ex.Message + ". Waiting " + DELAY_ON_ERROR + "ms.");
i--;
Thread.Sleep(DELAY_ON_ERROR);
}
while (i > 0);
if (i == -1)
SqlContext.Pipe.Send("Request is executed." + response);
}
static readonly int RETRY_COUNT = 3;
static readonly int DELAY_ON_ERROR = 50;
public static bool IsNullOrWhiteSpace(this string theString)
{
if (theString == null)
{
return false;
}
if (theString.Trim() == string.Empty)
{
return false;
}
return true;
}
private static void AddHeader(SqlChars H, WebClient client)
{
if (!H.IsNull)
{
string header = H.ToString();
if (!IsNullOrWhiteSpace(header))
client.Headers.Add(HttpRequestHeader.UserAgent, header);
}
}
};
And this how to use in SQL Query
declare #hkey nvarchar(4000) = 'SabaCertificate: 31336132353061666330315E235E756F6E6555E6261536974655E235E656E5F55535E235E536162615E235E24414021463393C69358BE384802BA1BBEAD3B4661862F193021435F7E28A30F7540FE661B9C5F30FDB06C';
declare #endpoint nvarchar(1000) = 'https://libertad-api.sabacloud.com/v1/location?count=10&startPage=1';
select curl.xget(#hkey, #endpoint)
I already test it in PostMan, entering the Header of SabaCertificate, and if it throws a result at me, however, when the certificate is not correct it also throws a response and it is not shown.
Bad Request Example:
{"errorCode":123,"errorMessage":"Invalid or expired Certificate"}
But it also does not give me the answer of the certificate error, that I have to change in my WebClient for this to work.
Added to this I think the certificate is too big because sometimes I get this error:
The identifier that starts with 'SabaCertificate:
31336132353061666330315E235E756F6E6555E6261536974655E235E656E5F55535E235E536162615E235E24414021463393C69358BE384802BA1BBEAD3B4661862F193021435F7E28A30F7540FE661B9C5F30FDB06C'
is too long. Maximum length is 128.
One definite problem in the code is a slight change you made to the original code. In your AddHeader method you have the following line:
client.Headers.Add(HttpRequestHeader.UserAgent, header);
You need to remove the HttpRequestHeader.UserAgent because the code is now creating a "UserAgent" header with a value of whatever you pass in, which is "SabaCertificate: 31336132....".
You will also need to change the security protocols that you are setting as they are not correct. You should try:
ServicePointManager.SecurityProtocol |= (SecurityProtocolType)3072; // TLS 1.2
Since you are using .NET 3.5 via SQL Server 2008 R2, you cannot specify SecurityProtocolType.Tls12 since that value had not yet been added to the enum in Framework Version 3.5, so you have to use the numeric value as shown above. Please keep in mind that the actual ability to do the security protocol is a function of the underlying OS, so it is possible that an older version of Windows / Windows Server does not support TLS 1.2, or might need a registry setting changed in order to do so. You will have to play around with that if you continue to get similar errors from System.Net.TlsStream.
Also, the following error:
The identifier that starts with 'SabaCertificate: 31336...30FDB06C' is too long. Maximum length is 128.
is from user-error. An "identifier" is an item name within SQL Server (objects, Logins, variables, etc). This means that you are doing something different (and wrong) when that error happens, but I can't see how it could be coming from your code, at least not the Get method, as that has no internal interaction with the database.

VSTO Outlook Plugin - HttpClient.PostAsync fails without fiddler

I unfortunately had Fiddler running for the whole time I was developing this feature in the plugin and since deploying to clients I found that it will not work for anyone - unless they run fiddler as well! It also does not work on my development machine if I stop running Fiddler.
The main error is Error while copying content to a stream.. So I investigated the possibility of the data I'm POSTing being released by the GC before it finished hitting the server (That, to me, explained why running Fiddler solved it - as I believe the request gets sent to Fiddler first, and then Fiddler sends it to the server). However I couldn't find anything to support that this might be the problem. I have tried making sure it holds onto the data but I don't feel like I'm going down the right route.
The code is roughly like this:
HttpClientHandler httpHandler = new HttpClientHandler { UseDefaultCredentials = true };
var client = new HttpClient(httpHandler, false);
client.BaseAddress = new Uri(BaseUrl + "api/job/PostTest");
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
content.Add(new StringContent(mailItem.HTMLBody, Encoding.UTF8), "BodyHtml");
// content.Add()'s... Omitted for brevity
var response = client.PostAsync(BaseUrl + "api/job/PostTest", content);
response.ContinueWith(prevTask => {
if (prevTask.Result.IsSuccessStatusCode)
{
System.Diagnostics.Debug.WriteLine("Was success");
}
else
{
System.Diagnostics.Debug.WriteLine("Was Error");
}
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion);
response.ContinueWith(prevTask =>{
MessageBox.Show(prevTask.Exception.ToString());
}, System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted);
The full exception details are:
System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
--- End of inner exception stack trace ---
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
---> (Inner Exception #0) System.Net.Http.HttpRequestException: Error while copying content to a stream. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.Net.WebException: The request was aborted: The request was canceled.
at System.Net.ConnectStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
--- End of inner exception stack trace ---
at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
--- End of inner exception stack trace ---<---
If anyone could point me to some resources that help me or point out where I'm going wrong that would help a lot!
When developing our IronBox Outlook plugin we ran into this issue. What we found was that within the VSTO context, the ServicePointManager supported security protocols was only Tls and Ssl3 (which was not going to work with our API which supported only TLS 1.2 or better).
You can check this easily from within your VSTO code like this (here's an example from when we hooked into Application.ItemSend event):
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Handle event when item is sent
this.Application.ItemSend += Application_ItemSend;
}
private void Application_ItemSend(object Item, ref bool Cancel)
{
foreach (var c in (SecurityProtocolType[])Enum.GetValues(typeof(SecurityProtocolType)))
{
if (ServicePointManager.SecurityProtocol.HasFlag(c))
{
Debug.WriteLine(c.ToString());
}
}
Cancel = false;
}
We solved it by setting the ServicePointManager.SecurityProtocol property to support Tls12 like this:
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
Hope this helps someone someday,
Kevin
After much searching and much messing about I've not been able to solve this problem using HttpClient so instead what I've done is using WebClient. In case someone else has this problem in the future I'm posting what I ended up using:
System.Net.WebClient wc = new System.Net.WebClient();
wc.Headers.Add("Content-Type", String.Format("multipart/form-data; boundary=\"{0}\"", multipartFormBoundary));
wc.UseDefaultCredentials = true;
try
{
var wcResponse = wc.UploadData(BaseUrl + "api/job/PostJobEmailNote", byteArray);
}
catch(Exception e)
{
// response status code was not in 200's
}
I think problem may be with using anonymous function that returns void. They're a little bit problematic. Changing my lambda to one that returns bools fixed the issue for me.

Silverlight HttpWebRequest BinaryReader second Read operation always takes a long time (12 seconds)

I am creating a Silverlight application that utilizes an H.264 MediaStreamSource implementation in order to stream live video from a server. I have a Multipart streamer that I wrote that reads the samples frame by frame.
When I connect to a server running on my local machine, it takes 12 seconds to read the second byte from the response stream in the ReadHeaders() function. So basically it connects to the host instantly, reads one byte successfully, the subsequent ReadByte() blocks (if you look at where the call stack is it is in another thread at: System.Windows.dll!MS.Internal.InternalNetworkStream.ReadOperation(object state)). Every time I test this it consistently takes the 12 seconds. Once this time has passed, all subsequent reads are immediate and the application runs great. If I use this same code in just a simple .NET console application, there is no 12 second delay.
Any idea what could be causing this?
byte[] imgBuf = new byte[ChunkSize * ChunkSize];
HttpWebRequest req = (HttpWebRequest)res.AsyncState;
int contentLength = 0;
try
{
HttpWebResponse resp = (HttpWebResponse)req.EndGetResponse(res);
// notify delegate of main headers
// get the response stream and start reading
BinaryReader reader = new BinaryReader(resp.GetResponseStream());
Dictionary<string, string> headers;
while (m_Running)
{
// read multipart response headers and notify delegate
headers = ReadHeaders(reader);
// check if end of stream
if (headers.ContainsKey(CustomHeaders.EndOfStreamHeader)
&& headers[CustomHeaders.EndOfStreamHeader] != null
&& String.Compare(headers[CustomHeaders.EndOfStreamHeader], "yes") == 0)
{
// notify delegate if end of stream has been reached
}
// determine length of data to read
string cl = headers["Content-Length"];
if (cl != null)
{
contentLength = Int32.Parse(cl);
}
byte[] data = reader.ReadBytes(contentLength);
if (data.Length > 0)
{
// notify delegate of multipart data
}
// Yield to other threads waiting to be executed
System.Threading.Thread.Sleep(1);
}
reader.Close();
resp.Close();
req.Abort();
}
catch (Exception ex)
{
// notify delegate of any errors that occurred
}
The ReadHeaders() function:
private Dictionary<string, string> ReadHeaders(BinaryReader reader)
{
List<byte> buffer = new List<byte>();
while (m_Running)
{
buffer.Add(reader.ReadByte());
if (buffer.EndsWith(EndOfHeaderBytes))
{
break;
}
// Yield to other threads waiting to be executed
System.Threading.Thread.Sleep(1);
}
return buffer.ToHeadersDictionary();
}
Edit: Here is the call stack of the two threads.
Worker Thread Worker Thread GenIIIWebClient.CVRESTLib.HttpMultipartStreamer.ReadHeaders Normal
[In a sleep, wait, or join]
mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) + 0x21 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x21 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x1f bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne() + 0x10 bytes
System.Windows.dll!MS.Internal.InternalNetworkStream.EndRead(System.IAsyncResult asyncResult) + 0x40 bytes
System.Windows.dll!MS.Internal.InternalNetworkStream.Read(byte[] buffer, int offset, int count) + 0x38 bytes
mscorlib.dll!System.IO.Stream.ReadByte() + 0x28 bytes
mscorlib.dll!System.IO.BinaryReader.ReadByte() + 0x1d bytes
GenIIIWebClient!GenIIIWebClient.CVRESTLib.HttpMultipartStreamer.ReadHeaders(System.IO.BinaryReader reader) Line 201 + 0x19 bytes
GenIIIWebClient!GenIIIWebClient.CVRESTLib.HttpMultipartStreamer.OnGetResponse(System.IAsyncResult res) Line 126 + 0xf bytes
System.Windows.dll!System.Net.Browser.ClientHttpWebRequest.InvokeGetResponseCallback.AnonymousMethod__18(object state2) + 0x11 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) + 0x3e bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x97 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x5a bytes
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x1b3 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes
[Native to Managed Transition]
[Appdomain Transition]
[Native to Managed Transition]
Unflagged 5096 5 Worker Thread Worker Thread [In a sleep, wait, or join] Normal
[In a sleep, wait, or join]
mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) + 0x21 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(long timeout, bool exitContext) + 0x21 bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x1f bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne() + 0x10 bytes
System.Windows.dll!MS.Internal.InternalNetworkStream.ReadOperation(object state) + 0x8a bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) + 0x3e bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x97 bytes
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x5a bytes
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x1b3 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes
[Native to Managed Transition]
[Appdomain Transition]
[Native to Managed Transition]
It is hard to see the real cause from here but it can be something related to thread management.
The first suspect I see here is m_Running. Focus on that. Maybe some threading stuffs vary for the types of projects.
Have you tried using a waitHandle instead of giving a Sleep(1),
ManualResetEvent waitHandle = new ManualResetEvent(false);
while(true)
{
waitHandle.Wait();
waitHandle.Reset();
while(ThereIsAJobToExecute)
{
// Process the jobs
// You should waitHandle.Set() in a callback or when you read it
}
}
My second offer for the line below is giving an initial list size
List < byte > buffer = new List < byte >();
Initial size for the type List<> DOES NOT mean a limit such an Array size. If you do not give a predefined size List resizes itself. So giving an expected number is a plus.
List<byte> buffer = new List<byte>(1024...etc);

Attempting to upload to FTP: System.Net.WebException: System error

I have an API that takes in XML and ultimately uploads files based on information in the XML. The uploads are on a schedule (also from XML), and I have tested everything surrounding it and know it works.
I am getting an error about 40% of the time on the first file that I attempt to upload in each time cycle (time cycle = 45 minutes for some files, 30 minutes for others).
Here is my code for the upload:
try {
LoggerFTP.Log("Uploading file: " + filename, false);
// Create the request.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(appSettingsFTP.ftpUrl + #"/" + filename);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = 6000000; //set to 100 minutes
//request.Timeout = -1; //set to infinite
// Add the login credentials.
request.Credentials = new NetworkCredential(appSettingsFTP.ftpLogin, appSettingsFTP.ftpPassword);
// Grab the file contents.
StreamReader sourceStream = new StreamReader(appSettingsFTP.uploadFileDirectory + filename);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
// Copy the file contents to the outgoing stream.
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
//Logger.Log(filename.ToString() + " " + "Upload Complete, Status: " + response.StatusCode + " " + response.StatusDescription, false);
//Took response.StatusDescription out because it appears to be creating extra line feeds.
LoggerFTP.Log(filename.ToString() + " " + "Upload Complete, Status: " + response.StatusCode, false);
}
catch (Exception ex) {
LoggerFTP.Log(ex.ToString(), false);
}
I have researched the issue and saw something online about it potentially being a speed thing. Like, there is a timeout. But I have my timeout set to 100 minutes for my FtpWebRequest, so it can't possibly be that? I don't know. This is also running as a service so it is hard to test this aspect of the code.
Here is the exception that is getting logged in my logger (e.ToString):
System.Net.WebException: System error. ---> System.Net.InternalException: System error.
at System.Net.PooledStream.PrePush(Object expectedOwner)
at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
at System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage)
at System.Net.FtpWebRequest.SyncRequestCallback(Object obj)
at System.Net.FtpWebRequest.RequestCallback(Object obj)
at System.Net.CommandStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at System.Net.ConnectionPool.Destroy(PooledStream pooledStream)
at System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse)
at System.Net.FtpWebRequest.AttemptedRecovery(Exception e)
at System.Net.FtpWebRequest.SubmitRequest(Boolean async)
--- End of inner exception stack trace ---
at System.Net.FtpWebRequest.GetRequestStream()
at CPMainSpringAPIExportsSC.UploadFTP.FTPUploadMethod(String viewname, String filename)
I am getting exactly the same stack trace in an SSIS package attempting to FTP over SSL. It works great without SSL, but as soon as I enable SSL, it blows up.
System.Net.WebException: System error. --->
System.Net.InternalException: System error. at
System.Net.PooledStream.PrePush(Object expectedOwner) at
System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse) at
System.Net.FtpWebRequest.FinishRequestStage(RequestStage stage) at
System.Net.FtpWebRequest.SyncRequestCallback(Object obj) at
System.IO.Stream.Close() at
System.Net.ConnectionPool.Destroy(PooledStream pooledStream) at
System.Net.ConnectionPool.PutConnection(PooledStream pooledStream, Object owningObject, Int32 creationTimeout, Boolean canReuse) at
System.Net.FtpWebRequest.AttemptedRecovery(Exception e) at
System.Net.FtpWebRequest.SubmitRequest(Boolean async)
--- End of inner exception stack trace --- at
System.Net.FtpWebRequest.CheckError() at
System.Net.FtpWebRequest.GetRequestStream() at
ST_0ff7348de65a468bb358ab0206e3721f.ScriptMain.Main() in c:\Users\Stephens\AppData\Local\Temp\Vsta\e664c8a71bb647ff9e9dc6ac32d7b615\ScriptMain.cs:line 155 at
System.Net.FtpWebRequest.CheckError() at
System.Net.FtpWebRequest.GetRequestStream() at
ST_0ff7348de65a468bb358ab0206e3721f.ScriptMain.Main() in c:\Users\Stephens\AppData\Local\Temp\Vsta\e664c8a71bb647ff9e9dc6ac32d7b615\ScriptMain.cs:line 155
Because the error is so generic, I decided to look at the .NET source to see if I can catch a clue about what is breaking. If you go here:
http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Net#{%22pageClientState%22%3A%22type-2844%2Ccsharp%22}
and skip down to line 281, you will see the definition for internal void PrePush(object expectedOwner) which is what is executing when the exception happens. Here is what it looks like:
internal void PrePush(object expectedOwner)
{
lock (this) {
//3 // The following tests are retail assertions of things we can't allow to happen.
if (null == expectedOwner) {
if (null != m_Owner && null != m_Owner.Target)
throw new InternalException();
// new unpooled object has an owner
}
else {
if (null == m_Owner || m_Owner.Target != expectedOwner)
throw new InternalException();
// unpooled object has incorrect owner
}
m_PooledCount++;
if (1 != m_PooledCount)
throw new InternalException();
// pushing object onto stack a second time
if (null != m_Owner)
m_Owner.Target = null;
}
}
Eventually I discovered that FtpWebRequest only supports explicit FTP (port 21) and not implicit FTP (port 990). This was definitively stated here:
Does .NET FtpWebRequest Support both Implicit (FTPS) and explicit (FTPES)?
Anyway, in my case, it was a firewall issue. Originally we configured for implicit FTP, which was ports 989, 990, 49152-65535 (per the vendor's tech staff). I checked with my network guy and we opened up ports 20, 21, 989, 990 and 40000-655535 for explicit and things worked like a champ afterwards.
However, in your case, you appear to have some connection pool excitement going on. There is a good post on this subject here:
How to improve the Performance of FtpWebRequest?
You might want to take a look at mucking around with your connection pool set up and see if you can make some progress. Hope this helps!
Regards,
Stuart
I know this is an old topic, but for anyone with the same problem, the code that is missing is:
request.EnableSsl = false;

Simple C# code freezes itself and all 32-bit applications (incl. VS2008) but only if run under a debugger with a breakpoint set

Background: As part of a small winforms app I'm developing I have a login screen. Besides the standard username/password fields it also has a third field - "Location" which is a dropdown containing possible geographical locations where a user can log on. The list of possible locations depends on the "distributor" to which the user belongs. Think of it as a user group, it's nothing more than that in reality.
To provide user friendliness I change the contents of the dropdown whenever a valid username is entered. Also the username textbox has autocomplete. Though this does offer some information disclosure, in this case it is not an issue.
The problem: When I type the first letter of my username in the textbox, autocomplete immediately completes it. The dropdown contents should also change. This happens fine if I run the program without debugger, but if the program is under debugger, everything freezes - both my app and Visual Studio. The autocomplete dropdown appears, but is empty. CPU usage is 0%. Only when I kill my app does Visual Studio unfreeze.
What is weirder, moving one line of code fixes the problem, although semantically everything is the same. Thus, this code works:
private void txtUser_TextChanged(object sender, EventArgs e)
{
string EnteredUserName = this.txtUser.Text.Trim();
var Found = this._NoLocations;
foreach ( var usr in this._AllUsers )
if (string.Compare(usr.FullName, EnteredUserName, StringComparison.CurrentCultureIgnoreCase) == 0)
{
Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usr.Distributor));
break;
}
this.bndLocation.DataSource = Found;
}
But this doesn't:
private void txtUser_TextChanged(object sender, EventArgs e)
{
string EnteredUserName = this.txtUser.Text.Trim();
var Found = null;
foreach ( var usr in this._AllUsers )
if (string.Compare(usr.FullName, EnteredUserName, StringComparison.CurrentCultureIgnoreCase) == 0)
{
Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usr.Distributor));
this.bndLocation.DataSource = Found;
break;
}
if ( Found == null )
this.bndLocation.DataSource = this._NoLocations;
}
I can also set breakpoints in this method and it will show that the method completes just fine, but the freeze happens afterwards.
What gives?
Oh, almost forgot - I'm using Visual Studio 2008 and Telerik RadControls Q3 2009. This didn't happen with windows standard controls, it only appeared after migration. Still, very weird.
Update 1: OK, so the second code fragment only works sometimes. But here's something weirder: it's not only VS2008 that freezes. My browser (Opera) and Windows Live! Messenger also became unresponsive. Thankfully the Task Manager and the Taskbar work just fine. This is getting more and more confusing...
Update 2: The variables _AllUsers, _AllLocations and _NoLocations are simple generic List<T>s. The User and Location classes are simple objects with simple properties. Although I am using NHibernate, so they might be automagically subclassed to something. bndLocation is the standard .NET BindingSource to which the Locations dropdown is bound.
Update 3: Wow, apparently all 32-bit processes are frozen. Or at least those with a UI. I'm able to start new apps, and they manage to initialize and show up, but then they freeze. For the record, I'm running Windows 7 x64.
Update 4: Here's the catch for Update 1: the code works if there are no breakpoints set in code. If there is a breakpoint set anywhere, it will freeze. The breakpoint doesn't have to be hit, it just has to be set. If I set the breakpoint after starting the program, all will be fine.
Update 5: As per request, here's the stack trace for the event:
ServiceTracker.exe!ServiceTracker.Forms.Login.txtUser_TextChanged(object sender = {Telerik.WinControls.UI.RadTextBox}, System.EventArgs e = {System.EventArgs}) Line 85 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.OnTextChanged(System.EventArgs e) + 0x68 bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxBase.textBoxItem_TextChanged(object sender = {Telerik.WinControls.UI.RadTextBoxItem}, System.EventArgs e = {System.EventArgs}) + 0x47 bytes
[Native to Managed Transition]
[Managed to Native Transition]
Telerik.WinControls.dll!Telerik.WinControls.RadItem.OnTextChanged(System.EventArgs e = {System.EventArgs}) + 0x80 bytes
Telerik.WinControls.dll!Telerik.WinControls.RadItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0xeb bytes
Telerik.WinControls.dll!Telerik.WinControls.RadHostItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0x5a bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxItem.OnPropertyChanged(Telerik.WinControls.RadPropertyChangedEventArgs e = {Telerik.WinControls.RadPropertyChangedEventArgs}) + 0x36c bytes
Telerik.WinControls.dll!Telerik.WinControls.RadObject.RaisePropertyNotifications(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object oldValue = "", object newValue = "v") + 0x2f7 bytes
Telerik.WinControls.dll!Telerik.WinControls.RadObject.SetValueCore(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object propModifier = null, object newValue = "v", Telerik.WinControls.ValueSource source = Local) + 0x5bb bytes
Telerik.WinControls.dll!Telerik.WinControls.RadElement.SetValueCore(Telerik.WinControls.RadPropertyValue propVal = {Telerik.WinControls.RadPropertyValue}, object propModifier = null, object newValue = "v", Telerik.WinControls.ValueSource source = Local) + 0xa2 bytes
Telerik.WinControls.dll!Telerik.WinControls.RadObject.SetValue(Telerik.WinControls.RadProperty property = {Telerik.WinControls.RadProperty}, object value = "v") + 0x9b bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxItem.TextBoxControl_TextChanged(object sender = {Text = "v"}, System.EventArgs e = {System.EventArgs}) + 0x168 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.OnTextChanged(System.EventArgs e) + 0x68 bytes
System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.WmReflectCommand(ref System.Windows.Forms.Message m) + 0xd2 bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.HostedTextBoxBase.WndProc(ref System.Windows.Forms.Message message = {msg=0x2111 (WM_REFLECT + WM_COMMAND) hwnd=0xf0478 wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x5ac bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 8465, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Control.SendMessage(int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x6c bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ReflectMessageInternal(System.IntPtr hWnd, ref System.Windows.Forms.Message m) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WmCommand(ref System.Windows.Forms.Message m) + 0x44 bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x1fd bytes
Telerik.WinControls.dll!Telerik.WinControls.RadControl.WndProc(ref System.Windows.Forms.Message m = {msg=0x111 (WM_COMMAND) hwnd=0xc046e wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x1ab bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.RadTextBoxBase.WndProc(ref System.Windows.Forms.Message m = {msg=0x111 (WM_COMMAND) hwnd=0xc046e wparam=0x3000478 lparam=0xf0478 result=0x0}) + 0x7a bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 273, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x9f bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x9e6 bytes
Telerik.WinControls.UI.dll!Telerik.WinControls.UI.HostedTextBoxBase.WndProc(ref System.Windows.Forms.Message message = {msg=0x102 (WM_CHAR) hwnd=0xf0478 wparam=0x76 lparam=0x2f0001 result=0x0}) + 0x5ac bytes
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x46 bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg = 258, System.IntPtr wparam, System.IntPtr lparam) + 0xad bytes
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason, int pvLoopData) + 0x5c3 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = 4, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.Application.ModalApplicationContext}) + 0x578 bytes
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x65 bytes
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) + 0x763 bytes
ServiceTracker.exe!ServiceTracker.Forms.Login.Authentificate(out ServiceTracker.Business.User user = null, out ServiceTracker.Business.Location location = null) Line 30 + 0x12 bytes C#
ServiceTracker.exe!ServiceTracker.Framework.Program.Main() Line 79 + 0x19 bytes C#
[Native to Managed Transition]
[Managed to Native Transition]
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x47 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x9b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x4d bytes
Update 6: So, I've come as far as to strongly suspect that there is a combination of a deadlock and a race condition somewhere between my app and other 32-bit apps. Which is strange, because even under a debugger the process is 64-bit. Anyways, here are the several possible scenarios that reproduce the problem:
The method changes the dropdown contents and there is a breakpoint ANYWHERE in my code. However if the breakpoint is OUTSIDE the if statement in the above method, everything works. Possibly that is because the breakpoint gets hit twice in a row - first when I enter the first letter; second when the autocomplete has provided the rest of the username.
If the method doesn't change the dropdown contents, but there is a breakpoint inside the if statement, everything freezes as well.
If the method contains just a Thread.Sleep(1000);, there is a freeze for exactly 1 second;
Otherwise no freeze.
So it smells like the event handler (or rather some method up the stack) takes a lock on some global resource which all other 32-bit processes need. Since VS2008 is a 32-bit process, it has to wait. But since there is a brekpoint, my app isn't running either, hence the deadlock. Also, changing the dropdown contents tries to take the same lock, and thus there is a deadlock within my app. If however there is a pause beforehand (when the breakpoint gets hit twice), the race condition doesn't happen and everything works again.
But... I cannot imagine what this global resource could be.
I don't know what your problem is, but I can point out some things that you are doing which could be causing problems:
Access to modified closure within lambda expression:
You should not access "usr" within a lambda expression since it is a closure within the foreach loop, and you can get some really weird behavior here. (the value of "usr" will be taken as the last one instead of the one it was created with.
It doesn't seem to me that this would be your problem. To see if it is, do this:
var usrTemp = usr;
Found = new List<Business.Location>(this._AllLocations.Where((a, b) => a.Distributor == usrTemp.Distributor));
I don't know what kind of LINQ provider you are using, or what your OnItemBound events look like, but in the first example you are biding your items when you still have an iterator open on _AllUsers. If your business layer isn't written as to support this concurrent access, this might be causing a problem.
To see if this is a problem change the foreach loop:
foreach (var usr in this._AllUsers.ToArray())
Have you ruled out the d'oh options of maybe hitting a breakpoint on an accessor property (possibly in a different thread) for this.bndLocation.DataSource?

Categories

Resources