2016-10-27 4 views
4

У меня есть проблема со следующим кодом, когда T-SQL прок вызывает ошибку (SQLException)Щеголеватых SqlException и Никто не замеченное исключение

var result = await conn.QueryMultipleAsync("Inventory.uspLoadItems", new 
    { 
     dbId = obj.myId, 
    }, 
    commandType: CommandType.StoredProcedure); 
    var items = await result.ReadAsync(); 
    var specificItems = MyCustomMapper.MapTo<MyItem>((dynamic)items); 

Я использую Dapper версию 1.50.2.

Процесс превращается в незаметное исключение.

Я могу следить за исключением вплоть до метода контроллера WebApi. Но когда существует метод контроллера, другой (нерезидентный и незавершенный) поток продолжает выполняться в var items = await items.ReadAsync();, даже если сеанс WebApi был завершен (собран GC?). (Текст удален из-за недопонимания в окне Parallell Stack. Исключение было не выполнено в ReadAsync, а не QueryMultipleAsync, и поэтому не продолжалось после исключения). Похож на проблему с резьбой в Dapper, но я не уверен.

UPDATE

Я нашел следующую ссылку на Microsoft Connect, который, кажется, очень близкие к этой теме. https://connect.microsoft.com/VisualStudio/feedback/details/2592987/sqldatareader-nextresultasync-causes-unobserved-task-exception-even-when-awaited

Итак, для всех, кто испытывает такое поведение. Вам придется подождать следующего обновления .NET.

Не Щеголеватая проблемы, но если Dapper-contributers может найти временную работу вокруг, что было бы неплохо :)

Сейчас я меняю все мое ReadAsync читать (синхронно), чтобы избежать этого SqlDataReader ошибки.

+0

не думаю, что это проблема с резьбой. Ожидайте результата. ReadAsync() будет вызываться в отдельном потоке, так как перед вами еще один ожидание. может уставить исключение здесь –

+0

В «Async-Await» нет потока, кроме вызывающего потока, Check: http://blog.stephencleary.com/2013/11/there-is-no-thread.html –

+0

Не могли бы вы попробуйте версию Sync 'QueryMultiple' и проверьте, наблюдается ли подобное исключение. В этом случае, как вы знаете, что сеанс веб-API - это сборник мусора (не существует способа узнать), просто теряется контекст. В фоновом режиме процесс ввода-вывода находится на том, что доступный обработчик отсутствует, он может дать незаметное исключение.Ожидаете ли вы в верхней части стека вызовов в контроллере Web API, что важно в этом случае, чтобы получить результат вызова. –

ответ

2

другая (нереста и незавершенная) нить продолжает выполняться в var items = waitait.ReadAsync();

Звучит как функция, которая существует во всем этом коде, выполняется асинхронно и не ожидается или иным образом синхронизируется с. Основной запрос завершается, пока эта функция все еще работает (это не догадка, это подтверждается вашим наблюдением, что код выполняется после завершения контроллера). Затем, если этот код сработает, исключение не обнаружено.

Было бы неправильным исправлением, чтобы игнорировать незаметные исключения. В любом случае я рекомендую это сделать, но правильным решением является ожидание задачи, частью которой является этот код.

Поскольку это ваш код, который все еще работает, это не ошибка структуры. Ошибка, с которой вы связались, может привести к тому, что код рамки будет выполняться позже и ненаблюдаем, но он не будет вызывать операторов после ожидания (снова).

+0

Я согласен с вами. Теперь я вижу, что мое наблюдение может быть неправильным. Я использовал окно Parallell Stacks, когда код был остановлен в моем обработчике TaskScheduler.UnobservedTaskException. В потоке, ведущем к исключению, зеленая линия (строка выполнения) была показана в ReadAsync после завершения процедуры контроллера. Я думал, что QueryMultipleAsync должен поднять исключение SqlException и, следовательно, предположить, что код был продолжен после исключения. Кажется, что исключения не поднимаются до ReadAsync и что окно Parallell Stack правильно отображает происхождение исключения. – Frode

+0

@Frode хорошо! – usr

Смежные вопросы