Я ожидаю, что, возможно, это простое исправление, но я просто не вижу его.
Я пытаюсь вставить данные в базу данных Azure Mobile Services из программы консоли С#. Однако, когда программа запускается из VS (через F5), данные не вставляются и не генерируются исключение (что я вижу) во время обычного хода запуска программы. Когда я устанавливаю await dataModel.InsertAsync(data)
останова на await dataModel.InsertAsync(data)
и запускаю ее в окне Immediate, она генерирует исключение ThreadAbortException. Любая помощь приветствуется.
Namespace TestApp {
class Program
{
public static MobileServiceClient MobileService = new MobileServiceClient(
"https://x.azure-mobile.net/",
"API key");
public static IMobileServiceTable<performance> dataModel = Program.MobileService.GetTable<performance>();
static void Main(string[] args)
{
try
{
var test = new performance("http://www.example.com");
var x = InsertItem(test);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
static public async Task InsertItem(performance data)
{
await dataModel.InsertAsync(data).ConfigureAwait(false);
}
}
class performance
{
[JsonProperty(PropertyName = "id")]
string Id { get; set; }
[JsonProperty(PropertyName = "uri")]
string Uri { get; set; }
public performance(string uri)
{
Uri = uri;
}
}
}
Я создал небольшой тест, чтобы (несколько) смоделировать то, что вы делаете. Когда ожидаемая задача в InsertItem занимает совсем немного времени или нет, задача, возвращаемая строкой var x = InsertItem (test), возвращает задачу в состоянии RanToCompletion, и отладчик действует так, как ожидалось.
Однако, когда я делаю ожидаемую задачу, делаю что-то существенное, например Thread.Sleep(5000), тогда я получаю описанное поведение, а задача, возвращаемая с помощью строки var x = InsertItem (test), возвращает задачу в WaitingForActivation государство.
Когда я ставил Task.WaitAll(x) после строки var x = InsertItem (test), тогда я получаю поведение, которое, как я думаю, мы ожидаем, и x.Status - это RanToCompletion.
Ваша проблема связана с тем, что var x = InsertItem(test);
является неблокирующим вызовом. Когда вы await dataModel.InsertAsync(data).ConfigureAwait(false);
функция InsertItem
немедленно возвращается с Task
.
Обычно правильный подход должен был бы await InsertItem(test);
однако, поскольку ваш код вызывается из Main
вы не можете выполнить функцию async
. Итак, для этого консольного приложения (это не будет правильным выбором, если вы работаете в WinForms или приложении WPF). Вам нужно поставить x.Wait()
до конца блока try-catch
.
static void Main(string[] args)
{
try
{
var test = new performance("http://www.example.com");
var x = InsertItem(test);
//This makes the program wait for the returned Task to complete before continuing.
x.Wait();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
Однако если вы делаете это в приложении WPF или WinForms, вы просто должны сделать функцию вызова (предположив, что функция была событием) async.
private async void Button1_OnClick(object sender, EventArgs e)
{
try
{
var test = new performance("http://www.example.com");
//The code now waits here for the function to finish.
await InsertItem(test);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
Не выполняйте вызовы функции async void
если вы не находитесь в функции делегата события
InsertAsync
останова и через F11, сеанс отладки останавливается сразу после вызоваInsertAsync
.