我正在从我的 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()
,代码按预期工作。
我看到了你的答案,但我认为这不是根本原因。使用static async Task Main()
是完全可以的,只要你的项目使用的是C#7.0或更高版本(引入时(。如果更改它(并使其他所有内容同步,就像删除async
后必须做的那样(使症状消失,那么这意味着在您的调用堆栈中的某个地方,您错过了一个await
。
例如,这工作得很好:
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");
}
}
但是,如果您在Main
中删除await
,则应用程序将在打印"完成暂停"之前结束。这是因为async
方法一开始同步运行,但在作用于不完整Task
的第一个await
返回。(Pause()
在遇到await Task.Delay(1000)
时返回一个Task
- 在等待完成之前(
因此,如果您没有await
async
方法,那么您的代码将在工作完成之前移动到下一行。有时你真的想要这个,但往往不是。
由于它以其他方式同步运行,因此用.Wait()
替换await
将停止线程并且该方法不会返回,使其突然"工作"。
在你的代码中,这意味着要么你没有等待createSite()
要么没有等待调用createSite()
的方法,等等。
Microsoft有一系列关于异步文章的写得很好的文章,值得一读。从这里开始:异步和等待的异步编程
感谢您对我最初帖子的评论。我现在让它工作了,并相信这是因为我将Main
方法定义为异步的,如下所示:static async Task Main()
.