Я пишу расширение Visual Studio на C # и получаю странное поведение при управлении исключениями и отображении сообщений об ошибках. По сути, я просто хочу добавить некоторые детали к сообщению об исключении, чтобы помочь мне разобраться в случае возникновения проблемы.
Все начинается с команды в элементе контекстного меню, и я подозреваю, что это может быть связано с управлением потоками за механизмом асинхронного ожидания / ожидания. Но я не уверен, что правильно угадал, и я не могу найти никакого решения. ПОМОГИТЕ!
Это начинается с моего обратного вызова пункта меню:
internal sealed class My_RunAnalysis
{
//...
public static async Task InitializeAsync(AsyncPackage package)
{
// Switch to the main thread - the call to AddCommand in PS_RunAnalysis's constructor requires
// the UI thread.
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService;
Instance = new My_RunAnalysis(package, commandService);
}
//...
private async void ExecuteAsync(object sender, EventArgs e)
{
try
{
await My_ViewModel.RunAnalysisAsync();
}
catch (Exception exc)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
//...
class My_ViewModel
{
async public static Task RunAnalysisAsync()
{
await My_Model.GetResultsListAsync();
}
}
//...
class My_Model
async public static Task GetResultsListAsync()
{
ResultsList = new My_ResultsList();
var rawResultsList = await QueryServerAsync<RawResultsListResponse>("GET", My_Request.GetResults());
//...
}
async public static Task<JsonResponse> QueryServerAsync<JsonResponse>(string method,
string request)
{
try
{
HttpResponseMessage response;
switch (method)
{
case "GET":
response = await _httpClient.GetAsync(request);
break;
case "POST":
default:
StringContent httpContent = new StringContent("", Encoding.UTF8, "application/json");
response = await _httpClient.PostAsync(request, httpContent);
break;
}
if (!response.IsSuccessStatusCode) //<<<<<<CASE #1
{
throw new My_Exception(
response.ReasonPhrase,
"Exception while querying server for " + request);
}
string serializedJson = await response.Content.ReadAsStringAsync();
// CASE #2>>>>>
var jsonResponse = serializer.Deserialize<JsonResponse>(serializedJson);
return jsonResponse;
}
catch (Exception e)
{
throw new My_Exception(
e.Message,
"Exception while querying server for " + request);
}
}
Странно то, что:
Когда возникает ошибка в случае #1, и я создаю пользовательское исключение (мой сервер ответил, но произошла внутренняя ошибка, и у меня есть чистый код ошибки), MessageBox в перехвате My_ViewModel :: RunAnalysisAsync () будет отображаться правильно и немедленно.
Когда в случае № 2 возникает собственное исключение (мой сервер ответил неправильно сформированным json, и я получаю исключение от serializer.Deserialize), MessageBox в перехвате My_ViewModel :: RunAnalysisAsync () не будет отображаться,IDE будет зависать примерно 15 секунд перед перезапуском (и все равно не будет отображать MessageBox).
Есть идеи, что случилось?
Спасибо!
РЕДАКТИРОВАТЬ:
Видя, что шаблон для моей пользовательской команды также инициализируется с помощью SwitchToMainThreadAsync, я попытался сделать то же самое с методом Execute. Я обновил приведенный выше код, но он по-прежнему не работает: исключение, выданное serializer.Deserialize, будет по-прежнему останавливать пользовательский интерфейс на 10–15 секунд, а MessageBox не будет отображаться!
Также обратите внимание, что отладчик может немедленно перейти к "await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync (package.DisposalToken);"и перейдите к следующему шагу в MessageBox. Я бы предпочел предположить, что это означает, что переключение на основной поток происходит немедленно, но все еще что-то не так ...
Есть идеи, что случилось? Мне действительно нужно надежно фиксировать исключения ...