WebClient.UploadFileAsync

G

GT

Hello,

Problem with catching exceptions in WebClient.UploadFileAsync.

VS 2005 winform project using WebClient.UploadFileAsync. Everything works
fine so far (with Progressbar + Credentials) but when an error occurs
(Server not reachable, Connection broken...) the exception is not caught, it
ends up with "Exception has been thrown by the target of an invocation" in
main(). When WebClient.UploadFile is used, evreything works fine.

WebClient wc = new WebClient();


wc.UploadFileCompleted += new
UploadFileCompletedEventHandler(UploadFileCallback);

wc.UploadProgressChanged += new
UploadProgressChangedEventHandler(UploadProgressCallback);

wc.Credentials = new NetworkCredential(uid, pw, "");

Uri uri = new Uri("http://server/file_receive.aspx");

try

{

wc.UploadFileAsync(uri, "POST", path2file);

}

catch (WebException wex)

{

throw (wex);

}

catch (Exception ex)

{

throw (ex);

}

Thanks a lot
 
F

Feng Chen[MSFT]

Hello GT,

The file specified by 'path2file' is sent asynchronously using a thread
that is automatically allocated from the CLR thread pool. The exception
should be thrown from this back ground thread, thus cannot be caught from
the main forefront thread which call the UploadFileAsync method. In
addition, the two callback methods (UploadFileCallback and
UploadProgressCallback) will also be called from this background thread.

To collect more detailed information about the exception, we can enable
'stopping in the debugger on first chance exceptions' option for all the
'Common language runtime exceptions', so that Visual Studio can break
immediately after the exception thrown in the background thread and before
the exception can be handled by handlers or CLR itself.
For more details about this option, please refer to <How to Stop on First
Chance Exceptions - Visual Studio 2005> -
http://blogs.msdn.com/davidklinems/archive/2005/07/19/440632.aspx.

In addition, we can also set the "Just My Code" option, so that VS will
only break in the codes written by our self. For more information about
this option, please visit
http://msdn.microsoft.com/en-us/vs2005/aa718464.aspx.

After Visual Studio breaks in our code, we should be able to see the
'$exception' item in the 'locals' window. Could you please post here the
Message and StackTrace of this exception object?

Please let me know the information above so I can proceed with the
troubleshooting process. I look forward to your reply.

Best regards,
Feng Chen
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications .

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx .
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

GT

Hello,

thanks for your reply.
Just to make things clear: my problem is that exceptions thrown by the
automatically allocated thread should by caught by the application, not just
in VS2005 but generally.
How can i do this?

Clients should be notified in an understandable manner, about what's wrong
(Server noch reachable...).

If you still need Message and StackTrace of the exception in Vs2005, let me
know.

best regards
 
F

Feng Chen[MSFT]

Hello GT,

An exception thrown from one thread can only be caught from this thread.
It's the thread's responsibility to handle the exception. Any unhandled
exception in a .net 2.0 application will terminate the application. And
there's a good discussion about this behavior: Handling "Unhandled
Exceptions" in .NET 2.0
(http://www.julmar.com/blog/mark/PermaLink,guid,f733e261-5d39-4ca1-be1a-c422
f3cf1f1b.aspx )

Before we can go any further about this issue, we need to figure out what
and where exactly the exception was thrown. So we'd appreciate if you can
post here this information.

There's another way to get notified when an exception unhandled in the
current AppDomain: subscribing to the AppDomain.UnhandledException Event
(http://www.google.com/search?q=AppDomain+UnhandledException+&sourceid=navcl
ient-ff&ie=UTF-8&rlz=1B3GGGL_zh-CNGB280GB280). In the handler of this
event, we can get the real exception been thrown:

AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
Exception appEx = e.ExceptionObject as Exception;
// Check appEx ' error message and stack trace information

Exception realException = appEx.InnerException;
if (realException != null)
{
// We can check here the StackTrace and error message of the innter
exception
}
}

Please note that this event can only notify us about the exception. After
that, the program will still terminate by default.

Please let me know the information so that I can provide further help, I
appreciate your time and patience.

Best regards,
Feng Chen
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

GT

Hello again,

i know where the exception happens, because it is prepared intentionally by
using an unreachable ip-adressto test the exception-handling as described in
the documentation.

In help there is following description for Exceptions thrown by
WebClient.UploadFileAsync

Exceptions
Exception type Condition
WebException
The URI formed by combining BaseAddress and address is invalid.

-or-

fileName is a null reference (Nothing in Visual Basic), is Empty, contains
invalid character, or the specified path to the file does not exist.

-or-

An error occurred while opening the stream.

-or-

There was no response from the server hosting the resource.

-or-

The Content-type header begins with multipart.


But this just doens't work, what is wuite confusing since normally the
documentation is quite godd. The function is exactly what i need, but where
is the sense if there is no exception handling altough it is described in the
documentation or am i doing something wrong.

However if an exception is thrown it shouldn´t terminate the programm,
that´s really stoneage!

best regards
 
F

Feng Chen[MSFT]

Hello GT,

It will be best if I get a sample project so that I can reproduce
troubleshoot this issue locally. In this way, we can work on this issue
more efficiently. Could you please send a sample project to my email box?
My email address is ([email protected], remove '.online').

If sending a project is not very convenient for you. Could you please help
to collect the stack trace and error message of the exception using the
method provided in my first reply?

I look forward to hearing from you and appreciate your time and patience.

Best regards,
Feng Chen
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
F

Feng Chen[MSFT]

Hello GT,

Thanks for sending me the project.

I tested it and found that the exception was actually thrown by calling the
UploadFileCompletedEventArgs.Result Property in the following line:
txt_Info.Text += System.Text.Encoding.UTF8.GetString(e.Result) + "\r\n";

For the WebException thrown in the WebClient.UploadFileAsync method, it
should be trapped in the UploadFileComplete event callback. If there is an
error uploading the file, this event will be fired, and the Error property
of the
UploadFileCompletedEventArgs(http://msdn.microsoft.com/en-us/library/system.
net.uploadfilecompletedeventargs(VS.80).aspx) passed to this event callback
method will contain an exception. This mechanism is different with normal
.Net exceptions since the method is executed asynchronously.

Under this situation, the Result Property of UploadFileCompletedEventArgs
will not be valid. The get_Result method will call the
RaiseExceptionIfNecessary method of the base class of
UploadFileCompletedEventArgs to throw a TargetInvocationException. The
following code was got using .net
reflector(http://www.aisto.com/roeder/dotnet) and showed this logic.

public byte[] get_Result()
{
base.RaiseExceptionIfNecessary();
return this.m_Result;
}
protected void RaiseExceptionIfNecessary()
{
if (this.Error != null)
{
// This is the exception thrown in Visual Studio.
throw new
TargetInvocationException(SR.GetString("Async_ExceptionOccurred"),
this.Error);
}
if (this.Cancelled)
{
throw new
InvalidOperationException(SR.GetString("Async_OperationCancelled"));
}
}

In addition, from the MSDN document of UploadFileCompletedEventArgs.Result
Property, we can see the following remarks:

You should check the Error and Cancelled properties to determine whether
the upload completed. If the Error property's value is an Exception object
or the Cancelled property's value is true, the asynchronous operation did
not complete correctly and the Result property's value will not be valid.

I modified the UploadFileCallback. Now we can catch the WebException and
the application will not crash any more.

public void UploadFileCallback(Object sender, UploadFileCompletedEventArgs
e)
{
if(e.Cancelled)
{
txt_Info.Text += "Cancelled\r\n";
}
else if (e.Error != null)
{
// There's an error thrown inside the UploadFileAsync method.
txt_Info.AppendText(e.Error.Message + Environment.NewLine);
txt_Info.AppendText(e.Error.InnerException.Message +
Environment.NewLine);
}
else
{
txt_Info.AppendText(System.Text.Encoding.UTF8.GetString(e.Result) +
Environment.NewLine);
txt_Info.AppendText( "Finish" + Environment.NewLine);
}

btn_Up.Enabled = true;
}

Please let me know if you have any other concerns or need any other help.

Best regards,
Feng Chen
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

GT

Hello.

thanks a lot, you really made my day!!

best regards


Feng Chen said:
Hello GT,

Thanks for sending me the project.

I tested it and found that the exception was actually thrown by calling the
UploadFileCompletedEventArgs.Result Property in the following line:
txt_Info.Text += System.Text.Encoding.UTF8.GetString(e.Result) + "\r\n";

For the WebException thrown in the WebClient.UploadFileAsync method, it
should be trapped in the UploadFileComplete event callback. If there is an
error uploading the file, this event will be fired, and the Error property
of the
UploadFileCompletedEventArgs(http://msdn.microsoft.com/en-us/library/system.
net.uploadfilecompletedeventargs(VS.80).aspx) passed to this event callback
method will contain an exception. This mechanism is different with normal
.Net exceptions since the method is executed asynchronously.

Under this situation, the Result Property of UploadFileCompletedEventArgs
will not be valid. The get_Result method will call the
RaiseExceptionIfNecessary method of the base class of
UploadFileCompletedEventArgs to throw a TargetInvocationException. The
following code was got using .net
reflector(http://www.aisto.com/roeder/dotnet) and showed this logic.

public byte[] get_Result()
{
base.RaiseExceptionIfNecessary();
return this.m_Result;
}
protected void RaiseExceptionIfNecessary()
{
if (this.Error != null)
{
// This is the exception thrown in Visual Studio.
throw new
TargetInvocationException(SR.GetString("Async_ExceptionOccurred"),
this.Error);
}
if (this.Cancelled)
{
throw new
InvalidOperationException(SR.GetString("Async_OperationCancelled"));
}
}

In addition, from the MSDN document of UploadFileCompletedEventArgs.Result
Property, we can see the following remarks:

You should check the Error and Cancelled properties to determine whether
the upload completed. If the Error property's value is an Exception object
or the Cancelled property's value is true, the asynchronous operation did
not complete correctly and the Result property's value will not be valid.

I modified the UploadFileCallback. Now we can catch the WebException and
the application will not crash any more.

public void UploadFileCallback(Object sender, UploadFileCompletedEventArgs
e)
{
if(e.Cancelled)
{
txt_Info.Text += "Cancelled\r\n";
}
else if (e.Error != null)
{
// There's an error thrown inside the UploadFileAsync method.
txt_Info.AppendText(e.Error.Message + Environment.NewLine);
txt_Info.AppendText(e.Error.InnerException.Message +
Environment.NewLine);
}
else
{
txt_Info.AppendText(System.Text.Encoding.UTF8.GetString(e.Result) +
Environment.NewLine);
txt_Info.AppendText( "Finish" + Environment.NewLine);
}

btn_Up.Enabled = true;
}

Please let me know if you have any other concerns or need any other help.

Best regards,
Feng Chen
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
F

Feng Chen[MSFT]

Hello GT,

I appreciate your update and response. Glad to hear that my suggestion
solved this issue. If you have any other questions or concerns, please do
not hesitate to contact us. It is always our pleasure to be of assistance.

Best regards,
Feng Chen
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top