我正在从我的C#代码中调用第三方库,并且发现ctx.CreateSiteAsync(communicationSiteInfo).Wait();
运行良好,而await ctx.CreateSiteAsync(communicationSiteInfo);
导致应用程序崩溃。据我所知,.Wait()
会导致线程阻塞,因此我很想让await
方法起作用。
这是我的代码的一部分,将上述调用置于上下文中:
public async Task createSite(string base_url, SiteConfig siteConfig) {
using(var ctx = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(base_url, this.applicationId, this.applicationSecret)) {
ctx.Load(ctx.Web, p => p.Title);
ctx.ExecuteQuery();
CommunicationSiteCollectionCreationInformation communicationSiteInfo = new CommunicationSiteCollectionCreationInformation {
Title = siteConfig.title,
Url = siteConfig.url,
SiteDesign = siteConfig.siteDesign,
Description = siteConfig.description,
Owner = siteConfig.ownerEmailAddress
};
try {
// This works: ctx.CreateSiteAsync(communicationSiteInfo).Wait();
await ctx.CreateSiteAsync(communicationSiteInfo);
} catch....
如果我没有记错的话,我称之为“ ClientContextExtensions.cs”的函数。
我是C#的新手,所以也许应用程序崩溃的原因很明显,但是我看不到为什么await
无法正常工作,因为我正在调用的函数具有async Task
在它的定义中。
编辑:关于异常的奇怪的事情是应用程序只是崩溃了,并且从未到达catch
子句。我不知道,但是也许这与线程或上下文有关,或者异步函数调用中抛出的异常不会返回到当前线程。应用程序在await ctx.CreateSiteAsync(communicationSiteInfo);
调用时崩溃。
编辑2:看来我可以简化当前的问题,但是以它为例:
public async Task StartMessageQueuePollAsync()
{
while (true)
{
await Task.Delay(1000).ConfigureAwait(false);
}
这会导致代码在await Task.Delay(1000).ConfigureAwait(false);
上崩溃。如果改为使用Task.Delay(1000).Wait()
,则代码将按预期工作。
答案 0 :(得分:0)
感谢您对我的第一篇文章的评论。我现在开始使用它了,并相信是因为我将Main
方法定义为异步方法,如下所示:
static async Task Main()
。
答案 1 :(得分:0)
我看到了您的答案,但我认为这不是根本原因。只要您的项目使用的是C#7.0或更高版本(引入该版本),就可以使用static async Task Main()
很好。如果进行更改(使所有其他内容保持同步,就像在删除async
之后所做的那样)使症状消失了,那么这意味着在调用堆栈的某个地方,您缺少了await
。
例如,this可以正常工作:
using System;
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
Console.WriteLine("Hello.");
await Pause();
Console.WriteLine("All done");
}
public static async Task Pause() {
await Task.Delay(1000);
Console.WriteLine("Done pausing");
}
}
但是,如果您删除await
中的Main
,则该应用程序将在打印“完成暂停”之前结束。这是因为async
方法最初是同步运行的,但是对不完整的await
起作用的第一个Task
则是 return 。 (Pause()
在到达Task
-之前等待完成时返回await Task.Delay(1000)
)
因此,如果您没有await
async
方法,那么您的代码将在完成工作之前移至下一行。有时您确实想要这个,但通常不需要。
由于它否则会同步运行,因此用await
替换.Wait()
会暂停线程并且该方法不会返回,从而使其突然“起作用”。
在您的代码中,这意味着您不是在等待createSite()
,就是在等待名为createSite()
的方法之类的东西,等等。
Microsoft有一系列关于异步文章的写得很好的文章,值得一读。从这里开始:Asynchronous programming with async and await