2011-06-14 27 views
6

Estoy trabajando con la clase System.Net.WebClient y estoy intentando subir un archivo utilizando el método UploadFileAsync. Estoy usando Visual Studio 2010, y todos mis proyectos están configurados para usar el tiempo de ejecución estándar .NET 4.0, no la biblioteca del cliente..NET error al llamar a System.Net.WebClient.UploadFileAsync

A continuación se muestra una pequeña sección del código que estoy usando. Aproximadamente el 90% del tiempo aparece el siguiente error:

No se puede convertir el objeto del tipo 'System.ComponentModel.AsyncOperation' para escribir 'UploadBitsState'.

Stack Trace: 
at System.Net.WebClient.UploadFileAsyncWriteCallback(Byte[] returnBytes, Exception exception, Object state) 
at System.Net.WebClient.UploadFileAsync(Uri address, String method, String fileName, Object userToken) 
at FileUpload._StartUpload() 

Los servidores FTP que estoy tratando de subir a son internas a mi organización, pero se está ejecutando alguna IPSwitches WS-FTP y el otro se está ejecutando un sitio FTP de IIS 6.0, y he experimentado el mismo problema con ambos servidores.

He buscado alto y bajo para otros con un problema similar en vano.

La línea real en la que se produce la excepción es la llamada al método _Client.UploadFileAsync.

private void _StartUpload() 
{ 
    try 
    { 
     _Client = new WebClient 
     { 
      Credentials = _Credentials 
     }; 
     _Client.UploadProgressChanged += ProgressChanged; 
     _Client.UploadFileCompleted += UploadCompleted; 
     _Client.UploadFileAsync(FileBeingUploaded, "STOR", _LocalFile, null); 
    } 
    catch (Exception exception) 
    { 
     // Methods calls removed for brevity 
    } 
} 

private void UploadCompleted(Object sender, UploadFileCompletedEventArgs e) 
{ 
    // Methods calls removed for brevity 
} 

private void ProgressChanged(object sender, UploadProgressChangedEventArgs e) 
{ 
    // Methods calls removed for brevity 
} 
+0

¿Funciona cuando lo ejecuta sincrónicamente? ¿Has intentado ver el tráfico con un detector de paquetes como 'tcpdump' o' WireShark'? –

+0

No he intentado una llamada síncrona. En cuanto a un sniffer, no he intentado ver estos errores específicos, pero dado que la excepción está dentro del marco .Net y es un problema de conversión, no estoy seguro de qué mostraría el análisis de tráfico TCP. –

+0

¿El archivo que está cargando '_LocalFile' es un archivo estático? En otras palabras, ¿hay ** alguna ** posibilidad de que el contenido del archivo se modifique/actualice mientras se carga? Lo pregunto porque puedo duplicar tu error en ese escenario en particular. –

Respuesta

4

Esto es un poco interesante. En cuanto a la fuente de referencia (WebClient.cs), la primera línea de UploadFileAsyncWriteCallback arroja el parámetro state al UploadBitsState.

En el método UploadFileAsync, hay algo de código de control de excepciones que dice:

catch (Exception e) 
{ 
    if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) 
    { 
     throw; 
    } 
    if(fs != null){ 
     fs.Close(); 
    } 
    if (!(e is WebException || e is SecurityException)) { 
     e = new WebException(SR.GetString(SR.net_webclient), e); 
    } 
    UploadFileAsyncWriteCallback(null, e, asyncOp); 
} 

asyncOp es de tipo AsyncOperation.

Parece que la llamada al UploadFileAsyncWriteCallback aquí es un error, porque está pasando un objeto del tipo incorrecto a la devolución de llamada. La devolución de llamada tiene un molde de estilo C (es decir, UploadBitsState uploadState = (UploadBitsState)state;).

Pero eso solo ocurrirá si algo desencadena una excepción durante la carga.

¿Es posible que algo en sus controladores de eventos ProgressChanged o UploadCompleted esté lanzando una excepción? O eso o uno de los parámetros que pasa a UploadFileAsync no es válido.

Más información

Realmente parece como si hubiera un error en UploadFileAsync. Por ejemplo, lo siguiente arroja InvalidCastException, cuando según la documentación debe arrojar WebException.

var targetUri = new Uri("ftp://example.com/file.txt"); 
var srcFile = string.Empty; // documentation says this will throw WebException 
var client = new WebClient(); 
client.UploadFileAsync(targetUri, "STOR", srcFile, null); 

He informó del fallo en https://connect.microsoft.com/VisualStudio/feedback/details/675575/webclient-uploadfileasync-throws-invalidcastexception

Sin embargo, desde el aspecto de las cosas que me dicen que la razón una excepción se está lanzando mentiras en el código. Desafortunadamente, es imposible decir donde, porque UploadFileAsync está perdiendo la información de la excepción. Quizás, como alguien más señaló, intentar una carga sincrónica arrojará más luz sobre el tema.

+0

Ambas funciones del controlador de eventos comienzan con try {y terminan con} catch (Exception exception) {// Handle exception} así que no creo que estén haciendo algo inapropiado. Tanto su respuesta como un comentario anterior apuntan a los parámetros de entrada que causan el problema. Tendré que ver si algo inesperado está cambiando los valores. –

+0

@DaleCouch: Lo siento, me refería al archivo de datos real en la unidad de disco que está cargando. Si, por ejemplo, era un archivo de registro para alguna otra aplicación. Si esa otra aplicación aún se está ejecutando mientras está cargando, entonces la otra aplicación podría agregar más datos de registro al registro. Esto podría confundir al cliente web desde que comenzó a pensar que estaba cargando 200 bytes, pero encuentra que el archivo ahora tiene 250 bytes de longitud. Sin embargo, todas las conjeturas de mi parte. –

+0

@ j.w.r .: Ahora eso parece tener más sentido. Eso es posible. Todos estos archivos se generaron en tiempo real, y acabo de cerrarlos antes de intentar transmitirlos. Por lo tanto, es muy posible que el sistema operativo se esté poniendo al día. Trataré de cambiar la forma en que lo hago y ver si eso ayuda. Gracias por la posible dirección. –

Cuestiones relacionadas