The following line hangs forever.
updateInfo = await mgr.CheckForUpdate();
I'm guessing it has something to do with acquiring a lock on a file? It's hard to diagnose without enabling logging. I was not able to enable logging per these instructions. If I register a logger in my program as in either of the below lines of code, nothing is logged. I'm guessing because the context of the program is different from the context of the update.exe.
Splat.Locator.CurrentMutable.Register(() => myLogger, typeof(Splat.ILogger));
Splat.Locator.CurrentMutable.Register(() => myLogger2, typeof(Splat.IFullLogger));
Any help diagnosing the check-update or forcing the log would be appreciated
It's a know bug : CheckForUpdate() doesn't return
It's the WebClient that deadlock when call from the main thread. The solution is to call Squirrel from a other thread, like :
static async Task CheckForUpdateSafe(this UpdateManager mgr)
{
await Task.Run(async () =>
{
await mgr.CheckForUpdate()
}
}
Related
I'm trying to add console commands to an existing ASP.NET Core 5 web application. The important part here is that I can set up all the dependency injection and configuration that is in the web application and use it in the console application as well. To do that I'm using the .NET Generic host in the following way:
public class ConsoleHostedService : IHostedService
{
private readonly IHostApplicationLifetime appLifetime;
public ConsoleHostedService(IHostApplicationLifetime appLifetime)
{
this.appLifetime = appLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
appLifetime.ApplicationStarted.Register(() =>
{
Task.Run(async () =>
{
try {
Console.WriteLine("1");
await Task.Delay(1000);
Console.WriteLine("2");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
// Stop the application once the work is done
appLifetime.StopApplication();
}
});
});
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}
This Host is executed from the following code:
public static void ExecuteCommand(string[] args)
{
Parser.Default.ParseArguments<CommandOptions1, CommandOptions2>(args)
.WithParsed<CommandOptions1>(async options =>
{
try
{
await Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
// configuration of dependency injection here
services.AddHostedService<ConsoleHostedService>();
})
.RunConsoleAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
}
})
.WithParsed<CommandOptions2>(o =>
{
// different command here
});
}
}
I'm using the CommandLineParser library here, though this part shouldn't matter for the problem. The actual generic host code was adapted from this blog post, which did seem to adress exactly what I needed.
The Problem is that the console application exits early, in my example where the await Task.Delay(1000) stands as a placeholder for my actual code I added some logging. The first line "1" is written to the console, the second line "2" is never written. I also get output for Microsoft.Hosting.Lifetime about the application stopping. The application seems to stop itself the moment it became ready, and any work I do in there that takes a bit of time is never executed at all.
I double checked all async/awaits and they're all there, the issue isn't a forgotten await. It does seem to be something about the Generic Host or the Lifetime itself, but those parts are pretty much entirely taken from the blog post I linked. I looked over all parts here, but I can't see any reason why the code would just shut down immediately.
Any idea what I'm doing wrong here, or what might cause the early shutdown?
Somewhere in the main console program it needs to know when to leave. Having it run an async call means that the program flow returns immediately after the setup call. Hence the console app is heading to the exit without waiting. You need to halt the console until the process ends.
In the main console app do something like:
Task.WaitAll( {the task(s) launched by the app} );
So the main program will halt its process execution flow while the other async processes run and smart wait until all of those task(s) are finished.
Or have some type of signal process to be sent when the async process ends and have the app check for that and shut down after it gets that event.
My good ladies and gentlemen, I recently had my first go at Worker services in .Net Core 3.1, and only the second go at Windows services in general (first one was made in .Net Framework and works fine to this day). If anyone could maybe shed some light at what I'm missing in the example that I will provide that would be great.
So, to keep it simple, my problem is this:
My supposed long (forever) running Worker service unexpectedly stops doing work at an arbitrary time of day, but still is shown as "Running" in service manager (that's probably how Windows deals with services). It doesn't necessarily have to be every day, but it stops doing work every now and then until I manually stop it and then restart it in Service Manager.
I have also stumbled upon this question which seemed to deal with my problem, but even after completely wrapping all of my service's code blocks in try-catchs, even on top-level, I still get nothing registered in my Log table, or even in the file I set up to write in if my DB connection fails. Service seems to just stop calling ExecuteAsync() method.
Ok here's how my code's logically structured, I have excluded implementation and I'm just showing what happens until DoWork is called:
public class Worker : BackgroundService
{
private readonly IConfiguration _configuration;
public Worker(IConfiguration configuration)
{
_configuration = configuration;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (true)
{
try //paranoid try-catch
{
await DoWork();
await Task.Delay(TimeSpan.FromSeconds(45), stoppingToken);
}
catch (Exception e)
{
await Log(e, customMessage: "Proccess failed at top level.");
}
}
}
catch (Exception e)
{
await Log(e, customMessage: "Proccess failed at topmost level.");
}
}
private async Task DoWork()
{
try
{
}
catch (Exception e)
{
await Log(e);
}
}
public async Task Log(Exception e, string user = null, string emailID = null, string customMessage = null)
{
}
}
As you can see, I am not handling cancellation, as in the question I linked above. Now that I think about it maybe I should, and something is inadvertently sending cancellation? The reason I didn't is because I'm not sure what events exactly signal the cancellation. Only the manual stopping of service, or something else maybe? And if it is the cancellation that was sent that caused my service to stop doing work, shouldn't it also stop my service from running?
Btw I just tested cancellation on dummy service which implements my logic with while(true) and it catches the stopping exception, even though it's a bit awkward, as it catches it and logs it multiple times before stopping, so I presume it may not be the cancellation token that is causing my DoWork not to fire.
Ok guys I'd fixed it. See comment below.
I'd guessed that what was causing deadlock was probably too many concurrent calls from different threads to database over the same connection.
Not that that I knew that would be the cause (and I still don't know and can only guess why this happens so if someone can clarify why this happens and why don't the calls get queued please do), but as I tried to fix it that seemed like a good starting point.
What I did was just limit possible concurrent calls to 1:
Instantiate SemaphoreSlim on a class level:
private static SemaphoreSlim Semaphore = new SemaphoreSlim(1);
Insert a SemaphoreSlim.WaitAsync before each of my DB calls and its respective SemaphoreSlim.Release in a finally block after the call:
try
{
await Semaphore.WaitAsync();
var id = await sqlCommand.ExecuteScalarAsync().ToString();
}
finally
{
Semaphore.Release();
}
I thought this would decrease the performance but to my pleasant surprise I felt no noticeable difference.
Also, I was tempted to set Semaphore's initial count to more than 1 thread but I figured if deadlock happens for many threads, then it might happen for 2-10 threads. Does anyone perhaps know anything more about this number? Is it processor related, SQL related, or perhaps C# related?
Have you implemented a dispose method to close the database connection after finishing the DoWork method? I had a deadlock problem using worker service and realized the database connection wasn’t disposed. After implementing a dispose method, it works for me to solve the problem.
Old question, and I don't know how or even if Manus's issue eventually resolved, but in my experience, exceptions in threads that aren't the main thread caused this problem for us in a Windows Service. And we didn't see this when running the same code as a Windows Forms. Try/catch wrapped around the main processing line does not catch them. We had to add it in the threaded method.
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.
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
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().
I just started playing with my fresh Raspberry Pi 3 and Win10 IOT.
I tried a little project but encountered some problems with async/await statements.
I am not new to C#, nor with await/async, but it is my first time with UWP so I may miss some tricks for this platform compairing to the WinForms/WPF environment.
(FYI, I haven't access to a Win10 developpement machine for the moment, so below snippets may not compile right away)
Here is the standard template for a headless application on the Rpi :
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.GetDeferral();
await DoSomethingAsync();
// Other irrevelant stuff then...
defferal.Complete();
}
And then an async method :
private async Task DoSomethingAsync()
{
// Something done async
await Task.Delay(1000);
} // <--- Hangs here
When deploying the app to the Pi, it enters the DoSomethingAsync method and execute its content without problem.
My issue is that the app hangs at the exiting semicolon.
Do we need to use the CoreDispatcher, the ThreadPool, or a simple new TaskFactory().StartNew(async () => { await DoSomethingAsync(); }); ?
What I don't understand is the use of the await/async should execute my method on an other thread, but it hangs the same way as if it was waiting for UI to process messages queue (WinForms/WPF background here :) )
Thank you in advance.
EDIT : This snippet works if I remove all the async stuff to make it synchronously running.
I don't see Complete() method on defferal in your code, try this:
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroudTaskDefferal defferal = taskInstance.GetDeferral();
await DoSomethingAsync();
// Other irrevelant stuff then...
defferal.Complete();
}
That could be problem with hanging, application's waiting for signal that async operations are completed.
If you remove all the breakpoints, add debugging logs like
`System.Diagnostics.Debug.WriteLine`
The debug message would show everything is working all fine.
The hang only happens when you do the remote debugging with VS.
I suggest you open an user voice request.
I have an ASP.NET MVC app with WebAPI controllers, and a console app that uses these controllers. The console app runs from a scheduled task and fetches data from remote sources, parses it, and posts it to the MVC app before exiting.
This works well for several of the controllers, but one of the calls is crashing the console app without throwing an exception. The caller code which is used for all the controllers:
public async Task<string> Post<T>(string urlRoot, string url, T data)
{
var result = "";
try
{
var httpClient = GetHttpClient(urlRoot);
var response = await httpClient.PostAsJsonAsync(url, data); // Exits here
if (response.IsSuccessStatusCode)
{
result = await response.Content.ReadAsAsync<string>();
}
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
return result;
}
The program exits when calling await httpClient.PostAsJsonAsync(url, data). Using breakpoints, neither the catch block nor the if statement are reached. The call is being made however, as the web API controller is being called with the correct data.
The programs share the same code for the T being passed across the API call.
From the output window:
The program '[9640] ProgramName.vshost.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
I was wondering whether the size of the posted data could be a problem, but I've not found any documentation stating size limits.
So my questions are:
What could be causing the console app to prematurely exit?
How can I detect this and prevent the program exiting?
One of possible problems, that you just don't await execution of Post method. Here is simplified version of what i am talking about:
static void Main(string[] args)
{
Action testAction = async () =>
{
Console.WriteLine("In");
await Task.Delay(100);
Console.WriteLine("First delay");
await Task.Delay(100);
Console.WriteLine("Second delay");
};
testAction.Invoke();
Thread.Sleep(150);
}
testAction will be aborted on second await Task, and console exits with 0 code. And output will be:
In
First delay
Press any key to continue . . .
In my case, i would just add Console.ReadKey() call at the end of Main method. In your case something different might be required
Please take a look at this question witch enumerates some Exceptions you need to handle:
.NET Global exception handler in console application
Application.ThreadException += MYThreadHandler;
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Also consider this aproach for Task Exceptions:
static void Main(string[] args)
{
Task<int> task = new Task<int>(Test);
task.ContinueWith(ExceptionHandler, TaskContinuationOptions.OnlyOnFaulted);
task.Start();
Console.ReadLine();
}
static int Test()
{
throw new Exception();
}
static void ExceptionHandler(Task<int> task)
{
var exception = task.Exception;
Console.WriteLine(exception);
}
You can find more detail in one of the answers of this question:
catch exception that is thrown in different thread
Once you hit await control will be returned to the caller of Post.
Rather than have await in the post method, use ContinueWith from the returned task, something like: Task continuation on UI thread or Wait on the returned task: http://msdn.microsoft.com/en-gb/library/dd537610.aspx
I would suggest testing to see if the JSON.Net serializer is capable of serializing your type.
"exited with code 0" means the program exited gracefully. Thus, it might be the caller of Post<T> or even above callers determine that it was time to end the program. If you are familiar with debugging tools such as WinDbg, you can set native breakpoints at ntdll functions to further diagnose the case, but normally you just need to review your code base.