Estoy creando una aplicación para el trabajo para copiar archivos y carpetas, con algunas opciones más, pero estas no se utilizan durante este problema.

La función en cuestión itera a través de cada archivo en un directorio, y luego copia el archivo a un directorio idéntico, en una nueva ubicación (para preservar las estructuras de archivos anidados).

La aplicación es un formulario de Windows, y debido a problemas al escribir en un cuadro de texto al mismo tiempo, he rodeado la función paralela en una Task.Factory.StartNew (), que solucionó ese problema.

Task.Factory.StartNew(() =>
{
    Parallel.ForEach(Directory.GetFiles(root, "*.*", SearchOption.AllDirectories), newPath =>
    {
        try
        {
            File.Copy(newPath, newPath.Replace(root, destination), false);
            WriteToOutput("recreated the file '" + newPath.Replace(root, destination) + "'");                                
         }
         catch (Exception e)
         {
             WriteToOutput(e.Message);
         }
     });
});

Cuando se ejecuta, las herramientas de diagnóstico muestran picos cada pocos segundos. ¿Cómo puedo 'igualar' estos picos y hacer que el rendimiento sea consistente? También estoy escribiendo en la pantalla para cada archivo que se mueve, y hay una pausa notable más o menos entre cada quizás, 20/25 archivos.

La siguiente captura de pantalla es una muestra de las Herramientas de diagnóstico.

enter image description here

c#
3
fauliath 3 mar. 2018 a las 00:44

3 respuestas

La mejor respuesta

Su trabajo está principalmente vinculado a IO, no a CPU. No tienes ningún trabajo para una CPU para hacer la mayor parte del tiempo. Solo está esperando que el disco duro haga su trabajo. Los picos en su CPU son simplemente los cortos períodos de tiempo después de que el disco ha finalizado una operación en la que la CPU está tratando de averiguar qué pedirle que haga a continuación, lo que lleva muy poco tiempo, por lo tanto, por qué ve picos, no mesetas.

5
Servy 2 mar. 2018 a las 21:48

Me preocupa esta frase:

debido a problemas al escribir en un cuadro de texto al mismo tiempo, he rodeado la función paralela en una Task.Factory.StartNew (), que solucionó ese problema

Sinceramente, dudo que haya solucionado el problema. Probablemente lo ocultó. No parece estar esperando o comprobando la Tarea, por lo que no está observando ninguna excepción. El corto pico de la CPU y el retraso en la salida podrían ser causados fácilmente por un desenrollamiento de la pila de algún tipo.

Si tiene problemas para actualizar la interfaz de usuario desde sus subprocesos de trabajo, asegúrese de comprender el propósito de Invocar y asegúrese de que lo está utilizando. Luego, deshazte de StartNew o asegúrate de manejar cualquier excepción.

3
John Wu 2 mar. 2018 a las 21:56

Lo que está haciendo es presionar el disco con muchas solicitudes de lectura de archivos en paralelo. Bueno, los discos, como cualquier otro dispositivo de E / S, no funcionan bien en ese modo.

Por un lado, si está leyendo el HDD, entonces definitivamente no puede responder las solicitudes paralelas simplemente porque tendría que mover el cabezal de lectura a múltiples ubicaciones al mismo tiempo.

Incluso con un SDD, el dispositivo no puede responder las solicitudes a la misma velocidad a la que la CPU puede preguntar.

En cualquier caso, el disco definitivamente no podrá devolver los datos a una velocidad uniforme. Muchas solicitudes de lectura de archivos estarán pendientes durante toda la eternidad (medido en tiempo de CPU), dejando esas tareas bloqueadas. Esa es la razón por la cual el rendimiento es desigual al asaltar el disco con muchas operaciones paralelas.

Al intentar procesar muchos archivos, puede optar por asignar una tarea para leerlos y luego procesar los datos cargados en paralelo. Piensa en ese diseño en su lugar. La tarea vinculada a E / S sería solo una y no se bloqueará más de lo necesario. Eso permitirá que la unidad devuelva los datos a la velocidad máxima que puede lograr en ese momento. Las tareas vinculadas a la CPU no se bloquearían, obviamente, porque sus datos ya estarían en la memoria en el momento en que se inicie cualquiera de las tareas. Esperaría que el diseño proporcione un rendimiento fluido.

1
Zoran Horvat 2 mar. 2018 a las 21:48