Reputation: 339
I'm calling a 3rd party library from my C# code, and have found that ctx.CreateSiteAsync(communicationSiteInfo).Wait();
works well, while await ctx.CreateSiteAsync(communicationSiteInfo);
causes the application to crash. As .Wait()
to the best of my knowledge causes the thread to block, I'm interested inn getting the await
approach to work.
Here an extract from my code to put the above calls in context:
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....
If I'm not mistaking, the function I'm calling it this one: ClientContextExtensions.cs.
I'm pretty new to C#, so perhaps the reason for the application crashing is obvious, but I can't see why the await
wouldn't work, as the function I'm calling has async Task
in it's definition.
EDIT: The weird thing regarding the exception is that the application simply crashes, and the catch
clause is never reached. I don't know, but maybe this has something to do with threading or context or something in that the exception thrown in the async function call are not returned to the current thread. The application crashes on the await ctx.CreateSiteAsync(communicationSiteInfo);
call.
EDIT 2: It looks as though I can simplify the issue at hand, but using this as an example instead:
public async Task StartMessageQueuePollAsync()
{
while (true)
{
await Task.Delay(1000).ConfigureAwait(false);
}
This causes the code to crash on await Task.Delay(1000).ConfigureAwait(false);
. If is instead use Task.Delay(1000).Wait()
, the code works as expected.
Upvotes: 0
Views: 1168
Reputation: 41008
I see your answer, but I don't think that's the root cause. It's perfectly fine to use static async Task Main()
, as long as your project is using C# 7.0 or higher (when that was introduced). If changing that (and making everything else synchronous, as you'd have to after removing async
) made the symptom go away, then that means that somewhere along your call stack, you were missing an await
.
For example, this works just fine:
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");
}
}
But if you remove the await
in Main
, then the application would end before "Done pausing" is printed. This is because async
methods run synchronously at first, but return at the first await
that acts on an incomplete Task
. (Pause()
returns a Task
when it hits await Task.Delay(1000)
- before the waiting is completed)
So if you don't await
an async
method, then your code will just move on to the next line before the work is done. Sometimes you actually want this, but often not.
Since it otherwise runs synchronously, replacing the await
with .Wait()
would halt the thread and the method would not return, making it suddenly "work".
In your code, that means that either you weren't awaiting createSite()
or weren't awaiting whatever called the method that called createSite()
, etc.
Microsoft has a series of very well-written articles about asynchronous articles that are worth reading. Start here: Asynchronous programming with async and await
Upvotes: 1
Reputation: 339
Thanks for the comments on my initial post. I got it working now, and believe it's because of I defined the Main
method to be async, like this:
static async Task Main()
.
Upvotes: 0