14

According the the MSDN documentation, Set() and Reset() on ManualResetEvent (or any EventWaitHandle) returns a boolean indicator whether or not the operation was successful.

Under which circumstances can this call return false, and what am I supposed to do if it does?

SoftMemes
  • 5,602
  • 4
  • 32
  • 61

2 Answers2

21

I wasn't sure how to answer this and looking at a lot of MSDN examples the Set return value is ignored so it must not be important or likely to happen.

But that wasn't good enough. I fired up my VM and I opened up Reflector to take a look at the code. ManualResetEvent doesn't have Set but it inherits from EventWaitHandle which does. Here's the code:

public bool Set()
{
    bool flag = Win32Native.SetEvent(base.safeWaitHandle);
    if (!flag)
    {
        __Error.WinIOError();
    }
    return flag;
}

Where SetEvent is imported from Kernel32:

[DllImport("kernel32.dll", SetLastError=true)]
internal static extern bool SetEvent(SafeWaitHandle handle);

The WinIOError() call just calls GetLastWin32Error which we don't really care about. Basically this means for the call to return false, something pretty wrong would have had to have occurred in the Win32 native code.

Putting this info together with the fact that code hosted in official MSDN documentation ignores the return value (why not? what are you going to do if the kernel fails anyway?) you can safely ignore it yourself if you want to clean your logic up a bit or get it and log it if you're especially pedantic.

Erik Noren
  • 4,279
  • 1
  • 23
  • 29
  • Thanks! It was an interesting question and it made me curious. – Erik Noren Nov 04 '10 at 02:09
  • 1
    Thanks Erik. Inspired by your work, I did the same thing and opened up Reflector. It looks like WinIOError() will always throw an exception that tries to represent the Win32 error code in the .NET world, which makes sense - but still doesn't really explain why the call has a return value! – SoftMemes Nov 04 '10 at 04:04
  • I can understand why looking at the Reflector decompilation would be useful, but please keep in mind that us [Mono](http://mono-project.com) contributors don't appreciate being exposed to a closed implementation, as it means that we cannot contribute to that area of Mono anymore. It's probably not a big deal in this case, but it's something to remember in the future. – cdhowie Dec 07 '12 at 19:51
  • 1
    @cdhowie - Is there a better way to handle this? I have to admit I don't tend to consider the implication of my answers on someone doing clean-room reimplementation of APIs or code. It's not something I do so it's not something I normally consider. The question wasn't marked in any way that would suggest an answer like this would be unwelcome and I was trying to be thorough. How should one approach this? Don't show code? Use a link to external site with the snippet? Is there any standard? To what questions does it apply? – Erik Noren Dec 12 '12 at 19:19
  • Showing the code of a closed implementation on a public website is probably never a good idea. In this case, the .NET Framework redistributable EULA does not (AFAICT) grant an exception to the "parent" Windows EULA that explicitly forbids reverse-engineering. Based on this information, using Reflector on Framework assemblies may be a breach of the EULA. (If you have any information to the contrary, please let me know.) – cdhowie Dec 13 '12 at 16:46
  • Ah - I hadn't considered exploring the source to supplement missing documentation on the library call itself could be considered reverse-engineering. I think we're in the clear on this one given the intent of the question and answer. I will try to be more thoughtful in the future so I don't expose a specific implementation of an API call. – Erik Noren Dec 13 '12 at 18:03
  • .NET source code is public. We share it all at https://referencesource.microsoft.com/ There is also a git hub project with the code for open source contribution by the community This specific code is at https://referencesource.microsoft.com/#mscorlib/system/threading/eventwaithandle.cs line 273 – David Burg Feb 05 '21 at 22:17
0

I am not sure that just log error and continue execution would be enought. False result from Set() can bring wrong behaviour in threads synchronozation managed by wait handlers. That is multithreading... My vision of handling false Set() result - throw exception, which probably in most cases can be unhandled.