我在一个简单的HTTP服务器上发生了统计崩溃,我写道, 尝试使用异步和等待使其异步单线程。
有时我会收到错误:
未处理的异常:System.AggregateException:发生了一个或多个错误。 ---> System.NotSupportedException:在上一个异步操作完成之前,在此上下文中启动了第二个操作。使用'等待'确保在调用此上下文中的另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
我似乎并不明白这是什么意思。是不是await的全部目的是能够在第一个操作时调用第二个操作?
相关代码是:
private static readonly BugScapeDbContext DBContext = new BugScapeDbContext();
private readonly CancellationToken _cancel = new CancellationToken();
public BugScapeServer() { }
public async Task Run() {
var listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8081/");
listener.Prefixes.Add("http://127.0.0.1:8081/");
listener.Start();
var saveChangesTask = PeriodicTask(SaveDBChangesAsync, TimeSpan.FromMilliseconds(10), this._cancel);
while (!this._cancel.IsCancellationRequested) {
await HandleRequestAsync(listener.GetContext());
}
await saveChangesTask;
}
private static async Task PeriodicTask(Func<Task> task, TimeSpan interval, CancellationToken token) {
while (!token.IsCancellationRequested) {
try {
await task();
} catch (Exception e) {
Console.WriteLine("Exception {0}", e.ToString());
}
await Task.Delay(interval, token);
}
}
private static async Task SaveDBChangesAsync() {
if (!DBContext.ChangeTracker.HasChanges()) return;
Console.WriteLine("Saving Changes...");
await DBContext.SaveChangesAsync();
}
private static async Task HandleRequestAsync(object state) {
var context = (HttpListenerContext)state;
var streamReader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding);
dynamic reqJson = await JsonConvert.DeserializeObjectAsync(await streamReader.ReadToEndAsync());
BugScapeResponse response;
switch ((EBugScapeOperation)reqJson.Operation) {
case EBugScapeOperation.GetMapState:
Console.WriteLine("Getting map state");
response = await HandleMapStateRequestAsync(reqJson);
break;
case EBugScapeOperation.Move:
Console.WriteLine("Moving character");
response = await HandleMoveRequestAsync(reqJson);
break;
default:
Console.WriteLine("Invalid operation {0}", (EBugScapeOperation)reqJson.Operatrion);
return;
}
if (response == null) {
response = new BugScapeResponse(EBugScapeResult.Error);
}
context.Response.ContentEncoding = Encoding.UTF8;
var resStream = new StreamWriter(context.Response.OutputStream, context.Response.ContentEncoding);
await resStream.WriteAsync(await JsonConvert.SerializeObjectAsync(response));
await resStream.FlushAsync();
context.Response.Close();
}
private static async Task<BugScapeResponse> HandleMapStateRequestAsync(dynamic request) {
var character = await DBContext.Characters.FindAsync(new object[] { (int)request.CharacterID });
if (character != null) return new BugScapeMapResponse(character.Map);
Console.WriteLine("No characeter found");
return null;
}
private static async Task<BugScapeResponse> HandleMoveRequestAsync(dynamic request) {
var character = await DBContext.Characters.FindAsync(new object[] { (int)request.CharacterID });
if (character == null) {
Console.WriteLine("No characeter found");
return null;
}
character.Move((EDirection)request.Direction);
return new BugScapeResponse(EBugScapeResult.Success);
}
完整堆栈跟踪是:
未处理的异常:System.AggregateException:发生了一个或多个错误。 ---&GT; System.NotSupportedException:在上一个异步操作完成之前,在此上下文中启动了第二个操作。使用&#39;等待&#39;确保在调用此上下文中的另一个方法之前已完成任何异步操作。任何实例成员都不保证是线程安全的。 在System.Data.Entity.Internal.ThrowingMonitor.EnsureNotEntered() 在System.Data.Entity.Internal.Linq.InternalSet
1.FindAsync(CancellationToken cancellationToken, Object[] keyValues) at System.Data.Entity.DbSet
1.FindAsync(CancellationToken cancellationToken,Object [] keyValues) 在System.Data.Entity.DbSet`1.FindAsync(Object [] keyValues) 在C:\ Users \ Bugale \ documents \ visual studio 2015 \ Projects \ BugScape \ BugScape \ Server.cs中的BugScape.BugScapeServer.d__8.MoveNext():第108行 ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在CallSite.Target(Closure,CallSite,Object) 在C:\ Users \ Bugale \ documents \ visual studio 2015 \ Projects \ BugScape \ BugScape \ Server.cs中的BugScape.BugScapeServer.d__6.MoveNext():第83行 ---从抛出异常的先前位置开始的堆栈跟踪结束--- 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.GetResult() 在C:\ Users \ Bugale \ documents \ visual studio 2015 \ Projects \ BugScape \ BugScape \ Server.cs中的BugScape.BugScapeServer.d__3.MoveNext():第48行 ---内部异常堆栈跟踪结束--- 在System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 在System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout,CancellationToken cancellationToken) 在System.Threading.Tasks.Task.Wait() 位于C:\ Users \ Bugale \ documents \ visual studio 2015 \ Projects \ BugScape \ BugScape \ Program.cs:第12行的BugScape.Program.Main(String [] args)