@@ -86,7 +86,7 @@ public async Task<bool> AcquireLockAsync(int millisecondsTimeout)
8686 // wait to get a write lock
8787 _sqlServerSyntax . WriteLock ( db , TimeSpan . FromMilliseconds ( millisecondsTimeout ) , Constants . Locks . MainDom ) ;
8888 }
89- catch ( SqlException ex )
89+ catch ( SqlException ex )
9090 {
9191 if ( IsLockTimeoutException ( ex ) )
9292 {
@@ -126,7 +126,7 @@ public async Task<bool> AcquireLockAsync(int millisecondsTimeout)
126126 }
127127
128128
129- return await WaitForExistingAsync ( tempId , millisecondsTimeout ) ;
129+ return await WaitForExistingAsync ( tempId , millisecondsTimeout ) . ConfigureAwait ( false ) ;
130130 }
131131
132132 public Task ListenAsync ( )
@@ -139,13 +139,15 @@ public Task ListenAsync()
139139
140140 // Create a long running task (dedicated thread)
141141 // to poll to check if we are still the MainDom registered in the DB
142- return Task . Factory . StartNew (
143- ListeningLoop ,
144- _cancellationTokenSource . Token ,
145- TaskCreationOptions . LongRunning ,
146- // Must explicitly specify this, see https://blog.stephencleary.com/2013/10/continuewith-is-dangerous-too.html
147- TaskScheduler . Default ) ;
148-
142+ using ( ExecutionContext . SuppressFlow ( ) )
143+ {
144+ return Task . Factory . StartNew (
145+ ListeningLoop ,
146+ _cancellationTokenSource . Token ,
147+ TaskCreationOptions . LongRunning ,
148+ // Must explicitly specify this, see https://blog.stephencleary.com/2013/10/continuewith-is-dangerous-too.html
149+ TaskScheduler . Default ) ;
150+ }
149151 }
150152
151153 /// <summary>
@@ -227,11 +229,29 @@ private void ListeningLoop()
227229 }
228230 finally
229231 {
230- db ? . CompleteTransaction ( ) ;
231- db ? . Dispose ( ) ;
232+ // Even if any of the above fail like BeginTransaction, or even a query after the
233+ // Transaction is started, the calls below will not throw. I've tried all sorts of
234+ // combinations to see if I can make this throw but I can't. In any case, we'll be
235+ // extra safe and try/catch/log
236+ try
237+ {
238+ db ? . CompleteTransaction ( ) ;
239+ }
240+ catch ( Exception ex )
241+ {
242+ _logger . Error < SqlMainDomLock > ( ex , "Unexpected error completing transaction." ) ;
243+ }
244+
245+ try
246+ {
247+ db ? . Dispose ( ) ;
248+ }
249+ catch ( Exception ex )
250+ {
251+ _logger . Error < SqlMainDomLock > ( ex , "Unexpected error completing disposing." ) ;
252+ }
232253 }
233254 }
234-
235255 }
236256 }
237257
@@ -245,37 +265,40 @@ private Task<bool> WaitForExistingAsync(string tempId, int millisecondsTimeout)
245265 {
246266 var updatedTempId = tempId + UpdatedSuffix ;
247267
248- return Task . Run ( ( ) =>
268+ using ( ExecutionContext . SuppressFlow ( ) )
249269 {
250- try
270+ return Task . Run ( ( ) =>
251271 {
252- using var db = _dbFactory . CreateDatabase ( ) ;
253-
254- var watch = new Stopwatch ( ) ;
255- watch . Start ( ) ;
256- while ( true )
272+ try
257273 {
258- // poll very often, we need to take over as fast as we can
259- // local testing shows the actual query to be executed from client/server is approx 300ms but would change depending on environment/IO
260- Thread . Sleep ( 1000 ) ;
261-
262- var acquired = TryAcquire ( db , tempId , updatedTempId ) ;
263- if ( acquired . HasValue )
264- return acquired . Value ;
274+ using var db = _dbFactory . CreateDatabase ( ) ;
265275
266- if ( watch . ElapsedMilliseconds >= millisecondsTimeout )
276+ var watch = new Stopwatch ( ) ;
277+ watch . Start ( ) ;
278+ while ( true )
267279 {
268- return AcquireWhenMaxWaitTimeElapsed ( db ) ;
280+ // poll very often, we need to take over as fast as we can
281+ // local testing shows the actual query to be executed from client/server is approx 300ms but would change depending on environment/IO
282+ Thread . Sleep ( 1000 ) ;
283+
284+ var acquired = TryAcquire ( db , tempId , updatedTempId ) ;
285+ if ( acquired . HasValue )
286+ return acquired . Value ;
287+
288+ if ( watch . ElapsedMilliseconds >= millisecondsTimeout )
289+ {
290+ return AcquireWhenMaxWaitTimeElapsed ( db ) ;
291+ }
269292 }
270293 }
271- }
272- catch ( Exception ex )
273- {
274- _logger . Error < SqlMainDomLock > ( ex , "An error occurred trying to acquire and waiting for existing SqlMainDomLock to shutdown" ) ;
275- return false ;
276- }
294+ catch ( Exception ex )
295+ {
296+ _logger . Error < SqlMainDomLock > ( ex , "An error occurred trying to acquire and waiting for existing SqlMainDomLock to shutdown" ) ;
297+ return false ;
298+ }
277299
278- } , _cancellationTokenSource . Token ) ;
300+ } , _cancellationTokenSource . Token ) ;
301+ }
279302 }
280303
281304 private bool ? TryAcquire ( IUmbracoDatabase db , string tempId , string updatedTempId )
0 commit comments