Я попал в эту очень странную ситуацию, когда я могу использовать await только один раз. См. Пример ниже:
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:
reached r1
Когда я запускаю отладчик и выполняю построчно, я могу выполнить до строки var r1 = ...
и дать ожидаемый результат в r1
, затем я нажимаю F10 , и отладчик просто завершает sh, как я бы нажал «Продолжить», и появится мой пользовательский интерфейс winform.
Отладчик никогда не вернется к код, когда вызов завершен. GetInstrumentAsync
метод просто выбирает запись из базы данных, используя EntityFramework (код ниже). И это действительно не займет много времени.
Кроме того, он не печатает ничего необычного в окне «Вывод» в разделе «Отладка».
Что я пробовал:
- Используйте
try/catch
, но он также никогда не попадет внутрь блока catch
. - Вызов
GetInstrumentAsync
с использованием .Result
и без await
. Это просто то же самое. - Я разработал нормальную версию этого метода (без
async/await
) и использую его, как ожидается. - Попробуйте запустить без отладчика (Ctrl + F5), чтобы убедиться, что это не так. Проблема, связанная с отладчиком. Но поведение остается тем же.
Я не могу понять, почему это происходит.
Код для GetInstrumentAsync
метода:
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;
}
}