我希望这可能是一个简单的解决办法,但我无法看到它。
我尝试从C#控制台程序将数据插入Azure移动服务数据库。但是,当程序从VS内部运行时(通过F5),数据没有被插入,也没有在运行程序的常规过程中抛出异常(我可以看到)。当我将断点设置为await dataModel.InsertAsync(data)
行并在立即窗口中运行它时会抛出一个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;
}
}
}
答案 0 :(得分:3)
您的问题来自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
次函数调用
答案 1 :(得分:1)
我创建了一个小测试(有些)模拟你正在做的事情。当InsertItem中等待的任务花费很少或根本没有时间时,var x = InsertItem(test)行返回的任务返回RanToCompletion状态的任务,调试器按预期运行。
然而,当我让等待的任务做一些实质性的事情,比如Thread.Sleep(5000),然后我得到你正在描述的行为,并且var x = InsertItem(test)行返回的任务返回一个任务处于WaitingForActivation状态。
当我在var x = InsertItem(test)行之后放置Task.WaitAll(x)时,我得到了我认为我们都期望的行为,而x.Status是RanToCompletion。