2016-08-22 2 views
1

Скажем, я использую APC, где процедура и вызывающий код используют SetLastError и GetLastError. Это приводит к непредсказуемым значениям из GetLastError. Есть ли выход из этого?Гонка GetLastError при вызове асинхронной процедуры

VOID CALLBACK MyFunction(ULONG_PTR param) 
{ 

    SetLastError(1); 
    // Doing some stuff here which takes some time 
    // Expecting 1 but can I/should I get 0 here ? 
    printf("LastError: %d\n", GetLastError());  
} 

int APCtry() 
{ 

    SetLastError(0); 

    DWORD dummy = 0; 

    if (!QueueUserAPC(MyFunction, GetCurrentThread(), dummy)) 
    { 
     return 0; 
    }  

    printf("LastError: %d\n", GetLastError()); 

    SleepEx(100, TRUE); 

    //SetLastError(0); Edited and commented 

    printf("LastError: %d\n", GetLastError()); 

    return 0; 
} 
+3

Не используйте SetLastError и GetLastError. Определите механизм отчетности об ошибках приложения. –

+1

@SamVarshavchik [Документация MSDN для 'GetLastError()'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms679360%28v=vs.85%29.aspx) указывает значение зависит от потока: * Возвращает значение кода последней ошибки вызывающего потока. Код последней ошибки поддерживается для каждого потока. Несколько потоков не перезаписывают код последней ошибки. * Я бы сказал, что вопрос требует гораздо больше данных. Там, конечно, нет [MCVE] (http://stackoverflow.com/help/mcve). –

+0

Я удалил теги языка, так как это концептуально, и вы не предложили никакого кода. Однако я подозреваю, что предоставление кода, вероятно, поможет вам получить более конкретные ответы. –

ответ

4

Вы всегда должны иметь 1 как LastError в MyFunction.

APCtry уже пошел вперед после MyFunction начал делать время трудоёмкая часть ...

Это большая путаница: весь код выполняется в одном потоке!

SleepEx begin... 
MyFunction... 
SleepEx return 
SetLastError(0); in APCtry() 

Так что SleepEx не возвращается до завершения MyFunction. Итак, то, что вы установили как последнюю ошибку после SleepEx (или то, что установлено SleepEx), не может влиять на MyFunction - потому что все это будет только после выхода MyFunction. То, что вы установите в качестве последней ошибки в MyFunction - это вы должны и получить здесь

EDIT

для большей ясности смотрите, что происходит внутри SleepEx: enter image description here

+0

Требуется, чтобы отредактировать этот ответ в первую очередь, но я даже не могу его понять ... – LBes

+0

@ LBes - что здесь вы не понимаете? Я говорю, что 'MyFunction' выполняется внутри вызова' SleepEx'. поэтому «APCtry уже пошел вперед после того, как« MyFunction »начал выполнять часть времени». - Абсолютно ошибочно. и никакой проблемы или гонки в использовании Get/Set LastError – RbMm

+0

Я говорю о языке здесь. Например, в вашем комментарии: «что здесь здесь, что вы не понимаете» ... Я знаю, что английский язык не является родным для всех (это тоже не мое), но нужно приложить минимальные усилия, чтобы дать понятный ответ. При этом я не говорю, что ваш ответ не очень хорош. Я не говорю о содержании, но формат – LBes

Смежные вопросы