async/await
在C#中使用时,通常的规则是避免,async void
因为这几乎是火,忘记了,Task
如果没有从方法发送返回值,则应该使用.说得通.但奇怪的是,在本周早些时候,我正在为async
我编写的一些方法编写一些单元测试,并注意到NUnit建议将async
测试标记为void
或者返回Task
.然后我试了一下,果然,它奏效了.这看起来很奇怪,因为nunit框架如何能够运行该方法并等待所有异步操作完成?如果它返回Task,它可以等待任务,然后做它需要做的事情,但是如果它返回void它怎么能把它拉下来呢?
所以我破解了源代码并找到了它.我可以在一个小样本中重现它,但我根本无法理解它们正在做什么.我想我对SynchronizationContext以及它是如何工作的了解不够.这是代码:
class Program
{
static void Main(string[] args)
{
RunVoidAsyncAndWait();
Console.WriteLine("Press any key to continue. . .");
Console.ReadKey(true);
}
private static void RunVoidAsyncAndWait()
{
var previousContext = SynchronizationContext.Current;
var currentContext = new AsyncSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(currentContext);
try
{
var myClass = new MyClass();
var method = myClass.GetType().GetMethod("AsyncMethod");
var result = method.Invoke(myClass, null);
currentContext.WaitForPendingOperationsToComplete();
}
finally
{
SynchronizationContext.SetSynchronizationContext(previousContext);
}
}
}
public class MyClass
{
public async void …
Run Code Online (Sandbox Code Playgroud) 我完成后有一个异步方法,我想运行另一个方法.如果我只是调用方法并添加.ContinueWith(),这可以正常工作
但是,我有一个新的要求,即只有在我能够将它添加到并发字典时才启动任务.
我希望构建任务,尝试添加它,然后启动任务
但是,似乎Task.Start()立即完成任务,导致继续操作运行,任何等待...等待.
谁能解释为什么会发生这种情况以及实现目标的正确方法?
namespace UnitTestProject2
{
[TestClass]
public class taskProblem
{
[TestMethod]
public void Test()
{
CancellationTokenSource cancel = new CancellationTokenSource();
ConcurrentDictionary<Guid, Task> tasks = new ConcurrentDictionary<Guid,Task>();
Guid id = Guid.NewGuid();
Task t = new Task(async () => await Get(), cancel.Token);
t.ContinueWith(Complete);
if (tasks.TryAdd(id, t))
{
t.Start();
}
else
{
//another thread is stopping stuff dont start new tasks
}
t.Wait(); //expected to wait for the get function to complete
Console.WriteLine("end test");
}
public async Task Get()
{ …
Run Code Online (Sandbox Code Playgroud)