C# 无法使用';等待&x27;不止一次

C# 无法使用';等待&x27;不止一次,c#,async-await,C#,Async Await,当我只能使用wait一次时,我陷入了一个非常奇怪的境地。请参见下面的示例: private async Task RegisterInstruments(byte clientId, RegisterInstrumentRequest registerInstrumentRequest, bool isPriority = false) { if (registerInstrumentRequest != null && registerInstrumentRequest.R

当我只能使用wait一次时,我陷入了一个非常奇怪的境地。请参见下面的示例:

private async Task RegisterInstruments(byte clientId, RegisterInstrumentRequest registerInstrumentRequest, bool isPriority = false)
{
  if (registerInstrumentRequest != null && registerInstrumentRequest.RegisterIntrstuments != null)
  {
    var r1 = await instrumentManager.GetInstrumentAsync("AMZN");
    logger.Debug("reached r1");
    var r2 = await instrumentManager.GetInstrumentAsync("AMZN");
    logger.Debug("reached r2");
  }
}
Serilog输出: 当我启动调试器并逐行执行时,我可以执行直到行
var r1=…
,并将预期结果输入
r1
,然后我按F10,调试器将刚刚完成,就像我单击“继续”一样,我的winform UI将出现

调用完成后,调试器不会返回代码。
GetInstrumentAsync
方法只是使用EntityFramework从数据库中获取记录(下面的代码)。这真的不需要太多时间

此外,它不会在调试部分的输出窗口中打印任何异常内容

我所尝试的:
  • 使用
    try/catch
    ,但它永远不会进入
    catch
  • 使用
    .Result
    调用
    GetInstrumentAsync
    ,而不使用
    wait
    。一模一样
  • 我开发了此方法的正常版本(没有
    async/await
    ),并按预期使用它
  • 尝试在没有调试器的情况下运行(Ctrl+F5),以确保它不是与调试器相关的问题。但行为还是一样
  • 我无法理解为什么会发生这种情况

    GetInstrumentAsync
    方法的代码: 公共异步任务GetInstrumentAsync(字符串全名) { 返回等待_dbContext.Instruments .AsNoTracking() .SingleOrDefaultAsync(m=>m.FullName==FullName); } 代码的其余部分(为了简洁起见,删除了一些语句):
    publicsocketmanager(框架)
    {
    socket.ReceiveReady+=SocketServer\u ReceiveReady;
    }
    //我无法执行此“异步任务”,因为这是一个偶数侦听器。它必须返回void而不是Task。所以我使用了。等等()
    私有void SocketServer_ReceiveReady(对象发送方,NetMQSocketEventArgs e)
    {
    ProcessMessage(例如Socket.ReceiveMultipartMessage()).Wait();
    }
    专用异步任务ProcessMessage(NetMQMessage netMQFrames,bool isPriority=false)
    {
    RequestMessageType messageType=(RequestMessageType)netMQFrames[2]。ConvertToInt32();
    字节clientId=netMQFrames[0]。缓冲区[0];
    字节[]messagBuffer=netMQFrames.FrameCount>3?netMQFrames[3]。缓冲区:null;
    开关(消息类型)
    {
    //为简洁起见,删除了其他案例
    案例请求MessageType.RegisterInstruments:
    RegisterInstrumentRequest RegisterInstrumentRequest=MessageParser.Deserialize(messagBuffer);
    等待RegisterInstruments(客户端ID、registerInstrumentRequest、iPriority);
    打破
    }
    }
    
    后台线程调用
    GetInstrumentAsync
    方法,它使用类的可重用实例(
    \u dbContext
    标识符)。这是一个实体框架类,所以在多线程应用程序中使用它时要小心。要么使用锁同步对单个实例的访问,要么在每个数据库请求上创建一个新实例。

    奇怪的是,就在这个特殊情况下(NetMQ),我没有得到线程安全异常,而当从多个线程访问
    \u dbContext
    时,我在应用程序中的某些其他位置也遇到了线程安全异常。在这种情况下,我确实创建了一个单独的
    \u dbContext
    实例。不知道为什么EF从来没有因为这个例子而抱怨过这个线程安全问题。可能在这个例子中,_dbContext被多个线程调用,但不是并发调用的。由于某些巧合的原因,请求可能被序列化。如果您不喜欢在每个请求上创建一个新的
    DbContext
    实例,那么可以使用类为每个线程存储一个单独的实例。我不确定这是否是一个好主意。评论不是为了进一步讨论;这段对话已经结束。
    reached r1
    
    public async Task<DsInstrument> GetInstrumentAsync(string fullName)
    {
      return await _dbContext.Instruments
        .AsNoTracking()
        .SingleOrDefaultAsync(m => m.FullName == fullName);
    }
    
    public SocketManager(Framework framework)
    {
      socket.ReceiveReady += SocketServer_ReceiveReady;
    }
    
    // I cannot make this `async Task` as this is an even listener. It must return void not Task. So I am using .Wait()
    private void SocketServer_ReceiveReady(object sender, NetMQSocketEventArgs e)
    {
      ProcessMessage(e.Socket.ReceiveMultipartMessage()).Wait();
    }
    
    private async Task ProcessMessage(NetMQMessage netMQFrames, bool isPriority = false)
    {
      RequestMessageType messageType = (RequestMessageType)netMQFrames[2].ConvertToInt32();
    
      byte clientId = netMQFrames[0].Buffer[0];
      byte[] messagBuffer = netMQFrames.FrameCount > 3 ? netMQFrames[3].Buffer : null;
    
      switch (messageType)
      {
        // Remved other cases for brevity
    
        case RequestMessageType.RegisterInstruments:
          RegisterInstrumentRequest registerInstrumentRequest = MessageParser.Deserialize<RegisterInstrumentRequest>(messagBuffer);
          await RegisterInstruments(clientId, registerInstrumentRequest, isPriority);
          break;
      }
    }