I'm investigating Microsoft enterprise library (data application block) -- The samples sln.
They have a sample of reading data asynchronously ( IAsync
, although the new ver (6) also support async
).
But Resharper(or visual studio- nevermind) shows me : "Access to disposed closure" : (first i will show the image , so it will be clearer , then i'll paste the code )
code :
/*1*/ [Description("Execute a command that retrieves data asynchronously")] /*2*/ static void ReadDataAsynchronously() /*3*/ { /*4*/ if (!SupportsAsync(asyncDB)) return; /*5*/ /*6*/ using(var doneWaitingEvent = new ManualResetEvent(false)) /*7*/ using(var readCompleteEvent = new ManualResetEvent(false)) /*8*/ { /*9*/ try /*10*/ { /*11*/ // Create command to execute stored procedure and add parameters /*12*/ DbCommand cmd = asyncDB.GetStoredProcCommand("ListOrdersSlowly"); /*13*/ asyncDB.AddInParameter(cmd, "state", DbType.String, "Colorado"); /*14*/ asyncDB.AddInParameter(cmd, "status", DbType.String, "DRAFT"); /*15*/ // Execute the query asynchronously specifying the command and the /*16*/ // expression to execute when the data access process completes. /*17*/ asyncDB.BeginExecuteReader(cmd, /*18*/ asyncResult = > /*19*/ { /*20*/ // Lambda expression executed when the data access completes. /*21*/ doneWaitingEvent.Set(); /*22*/ try /*23*/ { /*24*/ using(IDataReader reader = asyncDB.EndExecuteReader(asyncResult)) /*25*/ { /*26*/ Console.WriteLine(); /*27*/ Console.WriteLine(); /*28*/ DisplayRowValues(reader); /*29*/ } /*30*/ } /*31*/ catch (Exception ex) /*32*/ { /*33*/ Console.WriteLine("Error after data access completed: {0}", ex.Message); /*34*/ } /*35*/ finally /*36*/ { /*37*/ readCompleteEvent.Set(); /*38*/ } /*39*/ }, null); /*40*/ /*41*/ // Display waiting messages to indicate executing asynchronouly /*42*/ while (!doneWaitingEvent.WaitOne(1000)) /*43*/ { /*44*/ Console.Write("Waiting... "); /*45*/ } /*46*/ /*47*/ // Allow async thread to write results before displaying "continue" prompt /*48*/ readCompleteEvent.WaitOne(); /*49*/ } /*50*/ catch (Exception ex) /*51*/ { /*52*/ Console.WriteLine("Error while starting data access: {0}", ex.Message); /*53*/ } /*54*/ } /*55*/ }
Question :
Why is it giving this warning ? there is a manualreset-checked-signal
(which runs in a loop) which prevents the using
clause to be reached - which means - no dispose
will call .
So why does it yell (warning) ?
You pass doneWaitingEvent
to a lambda that may extend beyond the scope of the using block. I.e. there's a risk that Dispose
will have been called when the lambda executes.
It yells warning because the engine is not smart enough to figure out that the using block will never be exited before the delegate code completes. That is why this is a warning not a error.
You can safely ignore this warning, you can have resharper suppress the warning by wrapping the lines with special comments
asyncDB.BeginExecuteReader(cmd, asyncResult => { // Lambda expression executed when the data access completes. // ReSharper disable AccessToDisposedClosure doneWaitingEvent.Set(); // ReSharper restore AccessToDisposedClosure try { using (IDataReader reader = asyncDB.EndExecuteReader(asyncResult)) { Console.WriteLine(); Console.WriteLine(); DisplayRowValues(reader); } } catch (Exception ex) { Console.WriteLine("Error after data access completed: {0}", ex.Message); } finally { // ReSharper disable AccessToDisposedClosure readCompleteEvent.Set(); // ReSharper restore AccessToDisposedClosure } }, null);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With