Abnormal delay while starting execution of async Task method C# - c#

On timer elapsed I am calling an async method at every 1.5 seconds.
In the log file I can see time difference of 300ms between start of TimerElapsed and SendMessage method.
i.e. between "OnTimerElapsed : started" and "SendMessage: started".
Although it happens rarely after windows services runs for an entire day.
private async void OnTimerElapsed(object source, ElapsedEventArgs e)
{
SourceTrace.TraceVerbose("OnTimerElapsed : started");
await SendMessage();
SourceTrace.TraceVerbose("OnTimerElapsed : completed");
}
public async Task SendMessage()
{
SourceTrace.TraceVerbose("SendMessage: started");
var sendTask = Send(); // start sending
var getTask = GetData(); // update data
await Task.WhenAll(sendTask, getTask);
}
How can I get rid of such unusual high delay of 300-600ms occurring rarely and randomly?
I also tried running windows service as 'High Priority' process.
.Net framework version is 4.7.1
Update:
SourceTrace.TraceVerbose is wrapper on System.Diagnostics TraceSource and TextWriterTraceListener. It usually takes 1-2 ms to write the log.

Related

Orphaned async tasks in Azure Functions

What happens if in an Azure Function an async Task is started but orphaned before it finishes (it is never awaited), e.g.:
[Function("FuncAsync")]
public static async Task<HttpResponseData> FuncAsync(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "FuncAsync")]
HttpRequestData req,
FunctionContext context)
{
var obj = FactoryClass.GetObject(); // return some object with async LongTaskAsync method
obj.LongTaskAsync(); // async Task LongTaskAsync()
return req.CreateResponse(HttpStatusCode.OK);
}
The intention here was (I guess) to initiate a long running process and instantly return from the function.
I assume it is a bad practice but seems to work in a legacy code. I suspect there's no guarantee for the life of that async task and the azure process can be randomly winded up, when no function entry point is running/triggered.
For a console application if a running async Task is orphaned (and keeps running while the process terminates) it is abandoned/killed (and no exception is thrown).
class Program
{
public static async Task RunFuncAsync()
{
try
{
Console.WriteLine("Task started.");
await Task.Delay(10 * 1000);
Console.WriteLine("Task finished."); // this is never executed
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message); // this is never executed
}
}
static async Task MainAsync(string[] args)
{
var t = RunFuncAsync(); // no awaiting - purposefuly
await Task.Delay(5 * 1000);
Console.WriteLine("Exiting.");
}
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}
}
Output:
Task started.
Exiting.
C:\TestTasks_Console.exe (process 6528) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .
What happens if in an Azure Function an async Task is started but
orphaned before it finishes ?
The answer for the above question which you have is correct that it will get terminated. Azure Functions have many features that make our work a lot easier. However, stateless Azure Functions are not suitable for long running operations which would require to store a state of progress.
For such cases the Durable Functions are the best option. With this the restrictions on execution times no longer apply.
The task-based programming model and async/await are well suited for mapping workflows of Durable Functions.
If you check the Azure Function best practices, you will also find that we should avoid long running function and our function should be stateless.
Another option is to go for the WebJobs. You can use Azure WebJobs to execute custom jobs as background tasks within an Azure Web App
In conclusion, we can say that stateless Azure Functions not recommended for long running operations as you may get timeout issues or like in your case may get terminated.

Call a method on a specified time interval using C# [duplicate]

I need to publish some data to the service from the C# web application. The data itself is collected when user uses the application (a kind of usage statistics). I don't want to send data to the service during each user's request, I would rather collect the data in the app and send then all the data in a single request in a separate thread, that does not serve the users requests (I mean user does not have to wait for the request to be processed by the service). For this purpose I need a kind of JS's setInterval analog - the launch of the function each X seconds to flush all collected data to the service.
I found out that Timer class provides somewhat similar (Elapsed event). However, this allows to run the method only once, but that's not a big issue. The main difficulty with it is that it requires the signature
void MethodName(object e, ElapsedEventArgs args)
while I would like to launch the async method, that will call the web-service (input parameters are not important):
async Task MethodName(object e, ElapsedEventArgs args)
Could anyone advise how to solve the described task? Any tips appreciated.
The async equivalent is a while loop with Task.Delay (which internally uses a System.Threading.Timer):
public async Task PeriodicFooAsync(TimeSpan interval, CancellationToken cancellationToken)
{
while (true)
{
await FooAsync();
await Task.Delay(interval, cancellationToken)
}
}
It's important to pass a CancellationToken so you can stop that operation when you want (e.g. when you shut down your application).
Now, while this is relevant for .Net in general, in ASP.Net it's dangerous to do any kind of fire and forget. There are several solution for this (like HangFire), some are documented in Fire and Forget on ASP.NET by Stephen Cleary others in How to run Background Tasks in ASP.NET by Scott Hanselman
Here is a method that invokes an asynchronous method in periodic fashion:
public static async Task PeriodicAsync(Func<Task> action, TimeSpan interval,
CancellationToken cancellationToken = default)
{
while (true)
{
var delayTask = Task.Delay(interval, cancellationToken);
await action();
await delayTask;
}
}
The supplied action is invoked every interval, and then the created Task is awaited. The duration of the awaiting does not affect the interval, unless it happens to be longer than that. In that case the principle of no-overlapping-execution takes precedence, and so the period will be extended to match the duration of the awaiting.
In case of exception the PeriodicAsync task will complete with failure, so if you want it to be error-resilient you should include rigorous error handling inside the action.
Usage example:
Task statisticsUploader = PeriodicAsync(async () =>
{
try
{
await UploadStatisticsAsync();
}
catch (Exception ex)
{
// Log the exception
}
}, TimeSpan.FromMinutes(5));
.NET 6 update: It is now possible to implement an almost identical functionality without incurring the cost of a Task.Delay allocation on each loop, by using the new PeriodicTimer class:
public static async Task PeriodicAsync(Func<Task> action, TimeSpan interval,
CancellationToken cancellationToken = default)
{
using var timer = new PeriodicTimer(interval);
while (true)
{
await action();
await timer.WaitForNextTickAsync(cancellationToken);
}
}
The WaitForNextTickAsync method returns a ValueTask<bool>, which is what makes this implementation more efficient. The difference in efficiency is pretty minuscule though. For a periodic action that runs every 5 minutes, allocating a few lightweight objects on each iteration should have practically zero impact.
The behavior of the PeriodicTimer-based implementation is not identical with the Task.Delay-based implementation. In case the duration of an action is longer than interval, both implementations will invoke the next action immediately after the completion of the previous action, but the scheduler of the PeriodicTimer-based implementation will not slide forward like the Task.Delay-based implementation does. See the marble diagram below for a visual demonstration of the difference:
Clock X---------X---------X---------X---------X---------X---------X--
Task.Delay: +-----| +---| +------------|+---| +------| +--|
PeriodicTimer: +-----| +---| +------------|+---| +------| +--| +--
The scheduling of the Task.Delay-based implementation was permanently shifted forward, because the third invocation of the action lasted longer than the interval.
The simple way of doing this is using Tasks and a simple loop:
public async Task StartTimer(CancellationToken cancellationToken)
{
await Task.Run(async () =>
{
while (true)
{
DoSomething();
await Task.Delay(10000, cancellationToken);
if (cancellationToken.IsCancellationRequested)
break;
}
});
}
When you want to stop the thread just abort the token:
cancellationToken.Cancel();

Xamarin Android: C# Periodic Task (soft real-time)

I have extensively tried to search for this matter and could not reach any conclusion. I am using Xamarin with Visual Studio to design an app for Android in C# language. The app runs an async task which reads samples from the device microphone. So far there is no control of timing for this task. The code is as follows:
button.Click += async delegate
{
//do some other stuff
await read_mic_task();
}
The read_mic_task() is an async Task in which I read the samples from the microphone. I am measuring time between one and other execution using a Stopwatch and I can see the task runs with random periods. I would like to perform this task periodically and, despite searching a lot, I got nothing. Could you please give a help?
Thanks in advance!
There are multiple possibilities if you also want to share it across platforms i would go with system threading timer. This timer can also be used in a portable class.
You can use it for example like:
private System.Threading.Timer _timer;
...
// setup timer with callback
_timer = new System.Threading.Timer(OnTimerTick);
// start timer: duetime = 0 when to first execute callback (0 = right now) and intervall 5s
_timer.Change(0, 5000);
...
// stop timer
_timer.Change(Timeout.Infinite, Timeout.Infinite);
...
private void OnTimerTick(object state)
{
// do the intervall stuff here
}

Background Task gets cancelled by OS with BackgroundTaskCancellationReason as executiontimeexceeded

I have a UWP application where I have added background task support for doing certain things while my application is in background. I am doing exactly as it is mentioned here: https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task
I have one separate project for Background Tasks and in my package manifest file I have declared that my app uses background tasks (but "timer" task since I am using TimerTrigger). Code:
BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder { Name = "NotificationUpdater", TaskEntryPoint = "NamespaceOfMyBackgroundTaskInterfaceImplementation.BackgroundTask"};
backgroundTaskBuilder.SetTrigger(new TimeTrigger(15, false));
BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register();
Code inside BackgroundTask class:
namespace NamespaceOfMyBackgroundTaskInterfaceImplementation
{
public sealed class BackgroundTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
//Code to run in the background
taskInstance.Canceled += OnTaskInstanceCanceled;
}
private void OnTaskInstanceCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
_logger.LogInfo("Background Agent: The Operating System requested cancellation. Reason: {0}.", reason);
}
}
}
When I close my application, after 20-25 minutes the background task gets triggered but when it starts executing the Run() method, OS cancels the execution with BackgroundTaskCancellationReason as executiontimeexceeded. Sometimes the cancellation happens right after the background task starts executing.
Note: When I use lifecycle events dropdown in VS to trigger the background task, the OS never cancels the execution and it keeps running without any issues.
Edit: I added some logging to know the timings and here is what I found:
BG Task started at 5/4/2016 5:58:25 PM
BG Task Cancelled at 5/4/2016 5:58:50 PM
So it's not even waiting for 30 seconds (which is supposed to be the time limit for the background task execution) and it terminates it in approximately 25 seconds (in some cases this time difference was as low as 20 seconds).

Run async method regularly with specified interval

I need to publish some data to the service from the C# web application. The data itself is collected when user uses the application (a kind of usage statistics). I don't want to send data to the service during each user's request, I would rather collect the data in the app and send then all the data in a single request in a separate thread, that does not serve the users requests (I mean user does not have to wait for the request to be processed by the service). For this purpose I need a kind of JS's setInterval analog - the launch of the function each X seconds to flush all collected data to the service.
I found out that Timer class provides somewhat similar (Elapsed event). However, this allows to run the method only once, but that's not a big issue. The main difficulty with it is that it requires the signature
void MethodName(object e, ElapsedEventArgs args)
while I would like to launch the async method, that will call the web-service (input parameters are not important):
async Task MethodName(object e, ElapsedEventArgs args)
Could anyone advise how to solve the described task? Any tips appreciated.
The async equivalent is a while loop with Task.Delay (which internally uses a System.Threading.Timer):
public async Task PeriodicFooAsync(TimeSpan interval, CancellationToken cancellationToken)
{
while (true)
{
await FooAsync();
await Task.Delay(interval, cancellationToken)
}
}
It's important to pass a CancellationToken so you can stop that operation when you want (e.g. when you shut down your application).
Now, while this is relevant for .Net in general, in ASP.Net it's dangerous to do any kind of fire and forget. There are several solution for this (like HangFire), some are documented in Fire and Forget on ASP.NET by Stephen Cleary others in How to run Background Tasks in ASP.NET by Scott Hanselman
Here is a method that invokes an asynchronous method in periodic fashion:
public static async Task PeriodicAsync(Func<Task> action, TimeSpan interval,
CancellationToken cancellationToken = default)
{
while (true)
{
var delayTask = Task.Delay(interval, cancellationToken);
await action();
await delayTask;
}
}
The supplied action is invoked every interval, and then the created Task is awaited. The duration of the awaiting does not affect the interval, unless it happens to be longer than that. In that case the principle of no-overlapping-execution takes precedence, and so the period will be extended to match the duration of the awaiting.
In case of exception the PeriodicAsync task will complete with failure, so if you want it to be error-resilient you should include rigorous error handling inside the action.
Usage example:
Task statisticsUploader = PeriodicAsync(async () =>
{
try
{
await UploadStatisticsAsync();
}
catch (Exception ex)
{
// Log the exception
}
}, TimeSpan.FromMinutes(5));
.NET 6 update: It is now possible to implement an almost identical functionality without incurring the cost of a Task.Delay allocation on each loop, by using the new PeriodicTimer class:
public static async Task PeriodicAsync(Func<Task> action, TimeSpan interval,
CancellationToken cancellationToken = default)
{
using var timer = new PeriodicTimer(interval);
while (true)
{
await action();
await timer.WaitForNextTickAsync(cancellationToken);
}
}
The WaitForNextTickAsync method returns a ValueTask<bool>, which is what makes this implementation more efficient. The difference in efficiency is pretty minuscule though. For a periodic action that runs every 5 minutes, allocating a few lightweight objects on each iteration should have practically zero impact.
The behavior of the PeriodicTimer-based implementation is not identical with the Task.Delay-based implementation. In case the duration of an action is longer than interval, both implementations will invoke the next action immediately after the completion of the previous action, but the scheduler of the PeriodicTimer-based implementation will not slide forward like the Task.Delay-based implementation does. See the marble diagram below for a visual demonstration of the difference:
Clock X---------X---------X---------X---------X---------X---------X--
Task.Delay: +-----| +---| +------------|+---| +------| +--|
PeriodicTimer: +-----| +---| +------------|+---| +------| +--| +--
The scheduling of the Task.Delay-based implementation was permanently shifted forward, because the third invocation of the action lasted longer than the interval.
The simple way of doing this is using Tasks and a simple loop:
public async Task StartTimer(CancellationToken cancellationToken)
{
await Task.Run(async () =>
{
while (true)
{
DoSomething();
await Task.Delay(10000, cancellationToken);
if (cancellationToken.IsCancellationRequested)
break;
}
});
}
When you want to stop the thread just abort the token:
cancellationToken.Cancel();

Categories