Pregunta

Por alguna razón hay una pausa después del programa a continuación se inicia. Creo que WebClient().DownloadStringTaskAsync() es la causa.

class Program
{
    static void Main(string[] args)
    {
        AsyncReturnTask();

        for (int i = 0; i < 15; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }

    public static async void AsyncReturnTask()
    {
        var result = await DownloadAndReturnTaskStringAsync();
        Console.WriteLine(result);
    }

    private static async Task<string> DownloadAndReturnTaskStringAsync()
    {
        return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
    }
}

Por lo que yo entiendo mi programa debe empezar a contar de 0 a 15 inmediatamente. ¿Estoy haciendo algo mal?

Yo tenía el mismo problema con la muestra de descarga original de Netflix (que se obtiene con CTP ) - después de pulsar el botón de búsqueda de las primeras heladas de interfaz de usuario - y después de algún tiempo que es sensible mientras loadning las próximas películas. Y yo creo que no se congeló en la presentación de Anders Hejlsberg en el PDC 2010.

Una cosa más. Cuando en lugar de

return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));

Yo uso mi propio método:

return await ReturnOrdinaryTask();

Lo que es:

public static Task<string> ReturnOrdinaryTask()
{
    var t = Task.Factory.StartNew(() =>
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("------------- " + i.ToString());
            Thread.Sleep(100);
        }
        return "some text";
    });
    return t;
}

funciona como debería. Me refiero a que no se carga nada, pero comienza inmediatamente y no bloquea el hilo principal, mientras que hace su trabajo.

Editar

OK, lo que creo que en este momento es: la función WebClient.DownloadStringTaskAsync se arrugó. Debería funcionar sin el período de bloqueo inicial, de esta manera:

    static void Main(string[] args)
    {
        WebClient cli = new WebClient();
        Task.Factory.StartNew(() =>
            {
                cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
                cli.DownloadStringAsync(new Uri("http://www.weather.gov"));
            });

        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }
¿Fue útil?

Solución

Mientras que su programa hace el bloque por un tiempo, lo hace de ejecución curriculum vitae en el bucle, antes de que el resultado se devuelve desde el servidor remoto.

Recuerde que la nueva API asíncrono sigue siendo de un solo subproceso. Así WebClient().DownloadStringTaskAsync() todavía tiene que ejecutar en el hilo hasta que la solicitud ha sido preparado y enviado al servidor, antes de que pueda volver await y ejecución rendimiento a su flujo de programa en main ().

Creo que los resultados que observamos se deben al hecho de que se necesita algún tiempo para crear y enviar la solicitud a partir de su máquina. En primer lugar cuando ésta haya finalizado, la aplicación de DownloadStringTaskAsync puede esperar a que la red IO y el servidor remoto al completo, y puede devolver la ejecución en su caso.

Por otro lado, el método de RunOrdinaryTask simplemente inicializa una tarea y le da una carga de trabajo, y le dice a él para iniciar. Luego, vuelve inmediatamente. Es por eso que no se ve un retraso al usar RunOrdinaryTask.

Estos son algunos enlaces sobre el tema: de Eric Lippert el blog (uno de los diseñadores del lenguaje ), así como Jon entrada en el blog inicial de skeet al respecto. Eric tiene una serie de 5 mensajes sobre el estilo de continuación que pasa, lo que realmente es lo que async y await es realmente. Si se quiere entender la nueva característica en detalle, es posible que desee leer mensajes de Eric sobre CPS y asíncrono. De todas formas, ambos enlaces de arriba hace un trabajo bueno en la explicación de un hecho muy importante:

  • asíncrona! = Paralelo

En otras palabras, async y await no gira nuevos temas para usted. Ellos sólo permite reanudar la ejecución de su flujo normal, cuando usted está haciendo una operación de bloqueo -. Momentos en los que su CPU acaba de sentarse y no hacer nada en un programa síncrono, a la espera de alguna operación externa a completa

Editar

Para ser claro acerca de lo que está ocurriendo: conjuntos DownloadStringTaskAsync hasta una continuación, a continuación, llama WebClient.DownloadStringAsync, en el mismo hilo, y después rendimientos posterior ejecución de su código. Por lo tanto, el tiempo de bloqueo que está viendo antes del bucle empieza a contar, es el tiempo que toma a DownloadStringAsync completa. Su programa con asíncrono y esperar está muy cerca de ser el equivalente del siguiente programa, que exhibe el mismo comportamiento que su programa: un bloque inicial, comienza entonces a contar, y en algún lugar en el medio, los acabados op asincrónicos e imprime el contenido de la dirección URL solicitada:

    static void Main(string[] args)
    {
        WebClient cli = new WebClient();
        cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
        cli.DownloadStringAsync(new Uri("http://www.weather.gov")); // Blocks until request has been prepared

        for (int i = 0; i < 15; i++)
        {
            Console.WriteLine(i);
            Thread.Sleep(100);
        }
    }

Nota: Yo soy de ninguna manera un experto en este tema, por lo que podría estar equivocado en algunos puntos. No dude en corregir mi comprensión del tema, si usted piensa que esto está mal -. Yo miraba a la presentación PDC y jugaba con la última noche CTP

Otros consejos

¿Está seguro de que el problema no está relacionado con los valores de configuración de proxy que se detecta por el IE / Registro / En algún lugar lento?

Trate de establecer webClient.Proxy = null (o especificación de la configuración en app.config) y su período de "bloqueo" debe ser mínimo.

¿Está presionando F5 o CTLR + F5 para ejecutarlo? Con F5 hay un retardo para VS sólo para la búsqueda de los símbolos para AsyncCtpLibrary.dll ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top