Skip to content

Commit 0f90058

Browse files
committed
Suspend from a background thread in the TestEngine
Now, we push the suspension to a background thread and push execution back to the UI thread from within to avoid a potential deadlock on acquiring the suspension lock.
1 parent 8c629d8 commit 0f90058

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

Rubberduck.UnitTesting/UnitTesting/TestEngine.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Diagnostics;
44
using System.Linq;
55
using System.Runtime.InteropServices;
6+
using System.Threading.Tasks;
67
using NLog;
78
using Rubberduck.Parsing.Annotations;
89
using Rubberduck.Parsing.Symbols;
@@ -176,7 +177,8 @@ private void RunInternal(IEnumerable<TestMethod> tests)
176177
{
177178
return;
178179
}
179-
_state.OnSuspendParser(this, AllowedRunStates, () => RunWhileSuspended(tests));
180+
//We push the suspension to a background thread to avoid potential deadlocks if a parse is still running.
181+
Task.Run(() => _state.OnSuspendParser(this, AllowedRunStates, () => RunWhileSuspended(tests)));
180182
}
181183

182184
private void EnsureRubberduckIsReferencedForEarlyBoundTests()
@@ -198,6 +200,14 @@ private void EnsureRubberduckIsReferencedForEarlyBoundTests()
198200
}
199201

200202
private void RunWhileSuspended(IEnumerable<TestMethod> tests)
203+
{
204+
//Running the tests has to be done on the UI thread, so we push the task to it from within suspension of the parser.
205+
//We have to wait for the completion to make sure that the suspension only ends after tests have been completed.
206+
var testTask = _uiDispatcher.StartTask(() => RunWhileSuspendedOnUIThread(tests));
207+
testTask.Wait();
208+
}
209+
210+
private void RunWhileSuspendedOnUIThread(IEnumerable<TestMethod> tests)
201211
{
202212
var testMethods = tests as IList<TestMethod> ?? tests.ToList();
203213
if (!testMethods.Any())

0 commit comments

Comments
 (0)