Reputation: 2979
I need a way to perform some action synchronously which should complete in half a second, but might just hang around for minutes. If it times out I don't care about the result. Here's the I'm doing it right now using compiler-generated delegate.BeginInvoke:
static void Main()
{
bool disposed = false;
var wait = new ManualResetEvent(false);
var a = new Action(
() =>
{
Thread.Sleep(1000); // <- some looong action
if (!disposed)
lock (wait)
if (!disposed)
wait.Set();
});
a.BeginInvoke(a.EndInvoke, null);
bool success = wait.WaitOne(500);
Console.WriteLine(success ? "success" : "timeout");
lock (wait)
{
wait.Dispose();
disposed = true;
}
Console.ReadLine();
}
Looks ugly. And I'm aware lambda closure's disposed
variable is modified (unlike my ReSharper, I like this C# feature). All because I want to dispose ManualResetEvent
. Can you suggest better approach in .NET4? Perhaps should I just skip disposing the event and rely on GC?
One note: ManualResetEvent.Set()
explodes if you try to do it on disposed instance.
Upvotes: 5
Views: 1557
Reputation: 2979
Ugh, now that I looked a bit more at code samples using compiler-generated delegate.BeginInvoke
I see that it returns IAsyncResult
which has AsyncWaitHandle
exactly for my goal:
var a = new Action(() => Thread.Sleep(1000)); // <- some looong action
IAsyncResult asyncResult = a.BeginInvoke(a.EndInvoke, null);
bool success = asyncResult.AsyncWaitHandle.WaitOne(500);
That wait handle in case of AsyncResult
is in fact an instance of ManualResetEvent
which is disposed automatically from thread-pool thread right when my asynchronous call completes.
Upvotes: 3
Reputation: 74530
No, you should not skip the calling of the Dispose and rely on the GC. It's a waste of resources, plain and simple.
In .NET 4.0 I'd take a look at the Task Parallel Library, which is in the System.Threading assembly, new to 4.0.
Specifically, look at the Task class as well as the Wait method, which will allow you to specify a timeout.
Also, you will want to look at how to cancel a Task in the event it times out.
Upvotes: 4