I'm sure once the test is written, it'll point out some things that will need to be changed in order to get everything working with the UI, but basically I have this:
frmMain:
Dim totalFinished as Integer = 0
reporter as Func(Of Object) = Function()
                                totalFinished += 1
                                return Nothing
                              End Function
classWithAsync.setReporter(reporter)
classWithAsync.BeginCalculation() ' ignore that this is a private method call
' there is another method I'm leaving out (the public one) which just does
' some set up stuff and then calls BeginCalculation
' Note: this notice isn't actually in my code
ClassWithAsync:
Private Async Sub BeginCalculation()
  ' some logic here
  If synchronous Then
    CalculatorCalculate(calculator)
  Else
    Await calculatorAsyncCalculate(calculator)
  End If 
End Sub
Private Async Function calculatorAsyncCalculate(ByVal calculator as Calculatable) as Hashtable
  Dim result as Hashtable
  result = Await Tasks.Task.Run(Function() as Hashtable
                                 return calculator.Calculate()
                                EndFunction)
  reporter.Invoke()
  return result
End Function
Private Function CalculatorCalculate(ByVal calculator as Calculatable) as Hashtable
  Dim result as Hashtable
  result = calculator.Calculate()
  reporter.Invoke()
  return result
End Function
The intention here is to have reporter invoke twice. Which I have working in a synchronous version.. but the threaded test acts as if the thread didn't even run (which might be because the execution is continuing, and the assert is evaluating before the threads are finished?)
Here are my tests:
Synchronous: (Passes)
  <TestMethod> Public Sub UpdatesForEachSynchronousProduct() 
    Dim data As Hashtable = TestData.GenerateGroupData("LTD,WDL") 
    CreateMockCalculators(data, privateTarget) 
    privateTarget.SetFieldOrProperty("reporter", reporter) 
    privateTarget.SetFieldOrProperty("synchronous", True) 
    privateTarget.Invoke("BeginCalculation") 
    Assert.AreEqual(2, totalCalculated) 
  End Sub
Async: (Doesn't Pass)
<TestMethod> Public Sub UpdatesForEachAsyncProduct() 
    Dim data As Hashtable = TestData.GenerateGroupData("LTD,WDL") 
    CreateMockCalculators(data, privateTarget) 
    privateTarget.SetFieldOrProperty("reporter", reporter) 
    privateTarget.SetFieldOrProperty("synchronous", False) 
    privateTarget.Invoke("BeginCalculation") 
    Assert.AreEqual(2, totalCalculated) 
  End Sub 
The error for this one is that it expected 2, but totalCalculated was 0.
So, is there a way to make Assert wait until the threads are done?
 
    