.net - tareas - no se puede cambiar la prioridad acceso denegado windows 10
¿Cómo se puede aumentar la prioridad de I/O de un proceso? (5)
Quiero aumentar la prioridad de E / S de un proceso. Las respuestas para .NET y Windows Vista estarían bien. processexplorer está bien también.
La información relevante parece estar un poco dispersa en comparación con la documentación habitual de MS. Existe este documento que trata sobre la Priorización de E / S en Windows . Este documento parece tener indicadores beta por todas partes, pero supongo que probablemente sea bastante preciso.
Dos cosas importantes a tener en cuenta:
- Solo puede reducir la prioridad de las solicitudes de IO por debajo de lo normal.
- El conductor puede ignorar cualquier solicitud y tratarla como normal de todos modos.
Las API útiles para las aplicaciones cliente son SetFileInformationByHandle :
FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;
result = SetFileInformationByHandle( hFile,
FileIoPriorityHintInfo,
&priorityHint,
sizeof(PriorityHint));
// reduce CPU, page and IO priority for the whole process
result = SetPriorityClass( GetCurrentProcess(),
PROCESS_MODE_BACKGROUND_BEGIN);
// do stuff
result = SetPriorityClass( GetCurrentProcess(),
PROCESS_MODE_BACKGROUND_END);
SetThreadPriority que es similar:
// reduce CPU, page and IO priority for the current thread
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
// do stuff
SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
// reserve bandwidth of 200 bytes/sec
result = SetFileBandwidthReservation( hFile,
1000,
200,
FALSE,
&transferSize,
&outstandingRequests );
Para .Net haga las cosas habituales con P / Invoke.
Solo una actualización para esto: todo puede hacerse a través de .NET sin recurrir a WinAPI ...
// Set the current process to run at ''High'' Priority
System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
process.PriorityClass = System.Diagnostics.ProcessPriorityClass.High;
// Set the current thread to run at ''Highest'' Priority
Thread thread = System.Threading.Thread.CurrentThread;
thread.Priority = ThreadPriority.Highest;
He intentado lo anterior estableciendo la prioridad del proceso en una aplicación WPF y funciona bien. No he necesitado configurar la prioridad de subprocesos.
EDITAR: lo anterior se refiere a la prioridad de la CPU de un proceso, a diferencia de la prioridad de E / S; sin embargo, puede haber alguna correlación / conexión entre la prioridad de la CPU de un proceso y su prioridad de E / S.
Asegúrese de alinear FILE_IO_PRIORITY_HINT_INFO
estructura FILE_IO_PRIORITY_HINT_INFO
cuando llame a SetFileInformationByHandle
.
De lo contrario, obtendrá un ERROR_NOACCESS
(error 998, 0x000003E6).
_declspec(align(8)) FILE_IO_PRIORITY_HINT_INFO priorityHint;
priorityHint.PriorityHint = IoPriorityHintLow;
BOOL ret = SetFileInformationByHandle(hFile, FileIoPriorityHintInfo, &priorityHint, sizeof(FILE_IO_PRIORITY_HINT_INFO));
DWORD err = GetLastError();
La forma correcta de hacerlo es llamar a SetProcessPriorityClass con PROCESS_BACKGROUND_MODE_BEGIN para iniciar un modo de fondo. Esto causa una prioridad de E / S muy baja (fondo) y una prioridad de CPU inactiva. Cuando termine, llame a SetProcessPriorityClass nuevamente, suministrando PROCESS_BACKGROUND_MODE_END . Lo mismo se puede hacer en el nivel de subproceso a través de SetThreadPriority y THREAD_BACKGROUND_MODE_BEGIN / END.
Si desea establecer directamente la prioridad de E / S, independientemente de la prioridad de la CPU, debe utilizar las API nativas de NT. Lo documenté aquí , pero no incluí ejemplos de código, ya que todos sabemos que son arrancados textualmente.
La API que desea es la NT Native API NtSetInformationProcess . Al usar esta API puede cambiar la prioridad de E / S. Esta API acepta una variable de ''clase'' que le dice qué tipo de información sobre el proceso desea cambiar, esa variable de clase debe establecerse en ProcessIoPriority. A continuación, puede configurar la prioridad de E / S del proceso de esta manera.
Del mismo modo, la prioridad de E / S se puede recuperar a través de NtQueryInformationProcess .
La mala noticia es que los niveles de prioridad son un poco limitados. Critical está reservado para las operaciones de paginación del sistema. Eso te deja con Normal y Muy Bajo (Fondo). Bajo y Alto pueden o no implementarse en ediciones más nuevas de Windows. Parece haber un apoyo parcial, por lo menos.
Si no tiene experiencia con las API NT Native, lo primero que debe hacer es comprenderlas. Una vez que lo hagas, verás que es tan simple como una sola llamada API.
Parece que la forma "real" de establecer la prioridad de IO de un proceso es utilizando NtSetInformationProcess
con la clase de información ProcessIoPriority
. Lamentablemente, esta API no está documentada, pero puede verla en acción adjuntando un depurador a taskeng.exe y rompiendo ExeTask::GetYourPrioritiesStraight
.
Creo que el valor PROCESS_INFORMATION_CLASS
para ProcessIoPriority
es 33 (0x21) y los valores de prioridad son los siguientes:
Very Low: 0
Low: 1
Normal: 2
High: 3 or above?
Los valores anteriores son una buena estimación basada en lo que puedo decir del depurador; el planificador de tareas parece usar un valor de 1 para las tareas con prioridad 7, y un valor de 2 para las tareas con prioridad 5 (consulte esta pregunta y este artículo de MSDN para obtener más información sobre las prioridades del planificador de tareas). Llamar a SetPriorityClass
con PROCESS_MODE_BACKGROUND_BEGIN
usa un valor de 0.
Desafortunadamente, no he encontrado ninguna API pública que se pueda usar para esto, aparte del método SetPriorityClass
en la respuesta de @ 1800 INFORMATION, que establece la prioridad en Muy bajo.
Editar: he escrito una utilidad que se puede usar para consultar o establecer la prioridad IO de un proceso, disponible aquí .