I often have to execute code on a separate thread that is long running, blocking, instable and\or has a potential to hang forever. Since the existence of TPL the internet is full of examples that nicely cancel a task with the cancellation token but I never found an example that kills a task that hangs. Code that hangs forever is likely to be expected as soon as you communicate with hardware or call some third party code. A task that hangs cannot check the cancellation token and is doomed to stay alive forever. In critical applications I equip those tasks with alive signals that are sent on regular time intervals. As soon as a hanging task is detected, it is killed and a new instance is started.
The code below shows an example task that calls a long running placeholder method SomeThirdPartyLongOperation() which has the potential to hang forever. The StopTask() first checks if the task is still running an tries to cancel it with the cancellation token. If that doesn’t work, the task hangs and the underlying thread is interrupted\aborted old school style.
private Task _task;
private Thread _thread;
private CancellationTokenSource _cancellationTokenSource;
public void StartTask()
{
_cancellationTokenSource = new CancellationTokenSource();
_task = Task.Factory.StartNew(() => DoWork(_cancellationTokenSource.Token), _cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
public void StopTask()
{
if (_task.Status == TaskStatus.RanToCompletion)
return;
_cancellationTokenSource.Cancel();
try
{
_task.Wait(2000); // Wait for task to end and prevent hanging by timeout.
}
catch (AggregateException aggEx)
{
List<Exception> exceptions = aggEx.InnerExceptions.Where(e => !(e is TaskCanceledException)).ToList(); // Ignore TaskCanceledException
foreach (Exception ex in exceptions)
{
// Process exception thrown by task
}
}
if (!_task.IsCompleted) // Task hangs and didn't respond to cancellation token => old school thread abort
{
_thread.Interrupt();
if (!_thread.Join(2000))
{
_thread.Abort();
}
}
_cancellationTokenSource.Dispose();
if (_task.IsCompleted)
{
_task.Dispose();
}
}
private void DoWork(CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(Thread.CurrentThread.Name)) // Set thread name for debugging
Thread.CurrentThread.Name = "DemoThread";
_thread = Thread.CurrentThread; // Save for interrupting/aborting if thread hangs
for (int i = 0; i < 10; i++)
{
cancellationToken.ThrowIfCancellationRequested();
SomeThirdPartyLongOperation(i);
}
}
Although I’ve been using this construct for some years now, I want to know if there are some potential mistakes in it. I’ve never seen an example of a task that saves the underlying thread or gives it a name to simplify debugging, so I’m a bit unsure if this is the right way to go. Comment on any detail is welcome!
Code that hangs forever is likely to be expected as soon as you communicate with hardware or call some third party code.
Communication: absolutely not. There's always a way to timeout with communication APIs, so even with misbehaving hardware, there's no need to force-kill an I/O operation.
Third-party code: only if you're paranoid (or have high demands such as 24x7 automation).
Here's the bottom line:
There's no way to force-kill a task.
You can force-kill a thread, but this can easily cause serious problems with application state, possibility if introducing deadlocks in other parts of the code, and resource leaks.
You can force-kill an appdomain, which solves a large portion of app state / deadlock issues with killing threads. However, it doesn't solve them all, and there's still the problem of resource leaks.
You can force-kill a process. This is the only truly clean and reliable solution.
So, if you choose to trust the third-party code, I recommend that you just call it like any other API. If you require 100% reliability regardless of third-party libraries, you'll need to wrap the third-party dll into a separate process and use cross-process communication to call it.
Your current code force-kills a thread pool thread, which is certainly not recommended; those threads belong to the thread pool, not to you, and this is still true even if you specify LongRunning. If you go the kill-thread route (which is not fully reliable), then I recommend using an explicit thread.
The question is why is this task even hanging at all? I think there's no universal solution to this problem but you should focus on the task to be always responsible and not on forcing to interrupt it.
In this code, it looks like you're looking for a simple thread rather than a task - you shouldn't link tasks to threads - it's very likely that the task will switch to another thread after some async operations and you will end up on killing an innoccent thread that is not connected to your task anymore. If you really need to kill the whole thread then make a dedicated one just for this job.
You shouldn't also name or do anything with any thread that is used for tasks' default pool. Consider this code:
static void Main(string[] args)
{
Task.Run(sth);
Console.Read();
}
static async Task sth()
{
Thread.CurrentThread.Name = "My name";
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(Thread.CurrentThread.Name ?? "No name");
}
the output is:
3
4
No name
Related
I got following functions for making server calls
suspend fun <T: BaseResponse> processPost(post:Post):T? {
val gson=Gson()
val data=gson.toJson(post.reqData)
val res= sendPost(data,post.script)
Log.d("server","res:"+res.first)
//process response here
return null
}
private fun sendPost(data:String,url:String):Pair<String,Int> {
//send data to server
}
In some cases processPost may enter into infinite loop(for instance to wait for access token refresh).Of course this code should never be run on the main thread.But when I mark this function as suspend IDE is highliting it as redundant.Its not big deal but I'm curious how then can I restrict function execution on the main thread?
It seems that you have quite some learning on coroutines to do. It’s impossible to cover all you need to know in one single answer. That’s what tutorials are for. Anyway I will try to answer just the points you asked. It may not make sense before you learn the concepts, I’m sorry if my answer does not help.
Just like many other things, coroutines are not magic. If you don’t understand what something does, you cannot hope it has the properties you want. It may sound harsh but I want to stress that such mentality is a major cause of bugs.
Making a function suspending allows you to call other suspending functions in the function body. It does not make blocking calls non-blocking, nor does it automatically jump threads for you.
You can use withContext to have the execution jump to another thread.
suspend fun xyz() = withContext(Dispatchers.IO) {
...
}
When you call xyz in the main thread, it’ll hand the task to the IO dispatcher. Without being blocked, it can then handle other stuff in the app.
EDIT regarding the comment.
Sorry for being so patronizing and making a wrong guess about your misconception.
If you just want the compiler/the IDE to shut up about the warning, you can simply add #Suppress("RedundantSuspendModifier") to the function. But you shouldn't, because the compiler knows better than you, at least for now.
The great thing about coroutines is that you can write in direct style without blocking the main thread.
launch(Dispatchers.Main) {
val result = makeAnHttpCall() // this can take a long time
messWithUi(result) // changes to the UI has to be in the main thread
}
I hope it is obvious by now that the suspend modifier is not going to stop the main thread from calling the function.
#Suppress("RedundantSuspendModifier")
suspend fun someHeavyComputation(): Result {
return ...
}
launch(Dispatchers.Main) {
val result = someHeavyComputation() // this will run in the main thread
messWithUi(result)
}
Now if you want the computation not to be done in the main thread:
suspend fun someHeavyComputation() = withContext(Dispatchers.Default) {
... // this will be in a thread pool
}
Further reading: Blocking threads, suspending coroutines.
In my application I have the following:
db2.CreateTable<CategoryGroup>();
db2.CreateTable<Category>();
db2.CreateTable<CategoryGroupSource>();
db2.CreateTable<CategorySource>();
db2.CreateTable<Phrase>();
db2.CreateTable<PhraseSource>();
db2.CreateTable<Score>();
db2.CreateTable<Setting>();
From what I understand there is an Async way to do this also:
database.CreateTableAsync<TodoItem>().Wait();
Can someone explain if there is any advantage in me using the Async way and do people normally always use the Async?
Also are there likely to be benefits if I use this type of Async query:
public Task<TodoItem> GetItemAsync(int id)
{
return database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
}
When calling the methods on the main (UI) thread everything on the UI stops for as long as it takes that method to execute. If db2.CreateTable<CategoryGroup>() doesn't take up much time when doing it's thing, it shouldn't be a problem.
Doing a lot of time consuming actions straight after each other might affect your UI and make it freeze.
Calling the *Async variant of the method moves the work to a background thread, via the task API. Calling Wait() on that task, though, makes the current thread (in this case the UI thread) wait for the task to finish, and you're stuck with the same problem.
You should always await tasks: await database.CreateTableAsync<TodoItem>(). This will let it execute on a background thread and not make the current thread wait for it to finish. The next line in your code won't be executed until the Task is finished though. When you write the code, it makes the `Async variant look like it's behaving like the regular version.
Personally, I'd probably move all the methods into a task and just await that. That way you're not returning to the UI thread between each task to execute the next one:
await Task.Run(() =>
{
db2.CreateTable<CategoryGroup>();
db2.CreateTable<Category>();
db2.CreateTable<CategoryGroupSource>();
db2.CreateTable<CategorySource>();
db2.CreateTable<Phrase>();
db2.CreateTable<PhraseSource>();
db2.CreateTable<Score>();
db2.CreateTable<Setting>();
}
In this case you're making the database do all it's work on a background thread (and not freezing the UI while it's doing it). It then returns the result to the UI thread to enable you to update UI.
public Task<TodoItem> GetItemAsync(int id)
{
return database.Table<TodoItem>().Where(i => i.ID == id).FirstOrDefaultAsync();
}
what is the proper implementation of SendAsync method of Azure ServiceBus TopicClient?
In the second implementation, will the BrokeredMessage actually be disposed before the SendAsync happens?
public async Task SendAsync<TMessage>(TMessage message, IDictionary<string, object> properties = null)
{
using (var bm = MessagingHelper.CreateBrokeredMessage(message, properties))
{
await this._topicClient.Value.SendAsync(bm);
}
}
public Task SendAsync<TMessage>(TMessage message, IDictionary<string, object> properties = null)
{
using (var bm = MessagingHelper.CreateBrokeredMessage(message, properties))
{
return this._topicClient.Value.SendAsync(bm);
}
}
I would like to get most from await/async pattern.
Answer to your question: the second approach could cause issues with disposed objects, you have to wait ending of SendAsync execution before you can release resources.
Detailed explanation.
If you call await, execution of a method will be stopped at the same moment and will not continue till awaitable method is not returned. Brokered message will be stored in a local hidden variable and will not be disposed.
If you don't call await, execution will continue and all resources of brokered message will be freed before they are actually consumed (as using is calling Dispose on object at the end) or in the process of consumption. This definetely will lead to exceptions inside SendAsync. At this point, execution of SendAsync is actually started.
What await does is “pausing” any current thread and waits for completion of task and it's result. And that's what you actually need. Purpose of async-await is to allow execution of some task concurrently with something else, it provides ability to wait for a result of concurrent operation when it is really necessary and further execution isn't possible without it.
First approach is good if every method to the top is an async method too. I mean, if caller of your SendAsync is async Task, and caller of that caller and so on to the top calling method.
Also, consider exceptions that could raise, they are listed here. As you can see, there are so-called transient errors. This is a kind of errors that retry can possibly fix. In your code, there is no such exception handling. Example of retry pattern could be found here, but mentioned article on exceptions can suggest better solutions and it is a topic of another question. I would also add some logging system to at least be aware of any non transient exceptions.
I have one actor which is executing a forever loop that is waiting for the availability of data to operate on.
The doc says the Actor runs on a very lightweight thread, so I'm not sure whether i can use the thread.sleep() method on that actor. My objective is to not have that actor consume too much processing power.
So can I use the thread.sleep() method inside the actor ?
Don't sleep() inside Actors! That would cause the Thread to be blocked, causing exactly what you're trying to avoid - using up resources.
Instead if you just handle the message and "do nothing", the Actor will not use up any scheduling resources and will be just another plain object on the heap (occupying around a bit of memory but nothing else).
I just schedule to send a "WakeUp" message in a future time. Akka will send that message at predefined time, so the actor can handle and continue processing. This is to avoid using sleep.
// schedule to wake up
getContext().getSystem().scheduler().scheduleOnce(
FiniteDuration.create(sleepTime.toMillis(), TimeUnit.MILLISECONDS),
new Runnable() {
#Override
public void run() {
getContext().getSelf().tell(new WakeUpMessage());
}
},
getContext().getSystem().executionContext());
I see SetThreadExecutionState will prevent computer to sleep.
With boost::thread, how will I apply this to my software?
With disable_interruption?
That's an operation system specific function, and completely unrelated to threading.
It's related to power management.
You could run /a/ background thread that does this in a loop, though:
void background_thread() {
while (true) {
boost::this_thread::sleep_for(boost::chrono::seconds(30));
::SetThreadExecutionState(...); // whatever you want to do
}
}
Ironically, you would want to use interuption points in order to gracefully terminate that thread (although you can use whatever synchronization mechanism you prefer)