Cannot get C# Task exection flow to work properly [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've got an activity that I need to run on a background thread in a C#/XAML app, so I'm doing this:
Task.Factory.StartNew(() => ImportFile());
I'm returning the Task value to another bit of code that then needs to take action after the thread-based work has completed. The code looks like this:
Action<Task> finalise = async delegate { await FinishImport(dbList); };
dbList.ImportFileAsync().ContinueWith(finalise);
When I run the code, however, debugging statements in FinishImport are being executed before the background thread has finished.
What am I misunderstanding here? I thought the whole point of ContinueWith was that it would execute the continuation code after the target task completes.

You should use Task.Run rather than Task.Factory.StartNew in async code. Task.Run understands async methods while StartNew will return a Task representing only the beginning of that async method.
As a side note, it's usually best to not have Task.Run hidden inside a library method.
Also, it's far easier to use await than ContinueWith. And async methods should end with "Async".
So, applying these guidelines makes your code look like:
await Task.Run(() => dbList.ImportFileAsync());
await FinishImportAsync(dbList);

what ImportFileAsync() does?
finalise will run after the thread of ImportFileAsync() will end
if
ImportFileAsync(){ Task.Factory.StartNew(() => ImportFile());}
then ImportFileAsync will call a new thread for ImportFile() and then exit it won't wait for ImportFile()
to finish
you wanna do
Task.Factory.StartNew(() => dbList.ImportFile()).ContinueWith(finalise);

Related

How to wait until operations within a foreach loop are completed before iterating again in C#? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 days ago.
Improve this question
I currently am running the following code:
async Task Method()
{
foreach (DataGridViewRow row in dataGridView1.Row)
{
// Do Something
}
await Task.Delay(120000);
}
However this obviously does only wait for a certain time. Now I am wondering how to change it, so that it will wait until one iteration inside the foreach loop is completely independent of time to then start another iteration until the loop/loops are completed.
I have read about Task.WhenAll() but I don't get it. I could also put my Method() in a foreach loop if it is required or preferred.
If the code inside the loop is synchronous, then the statements inside of the loop will complete before you get to your awaited delay. If you have asynchronous statements inside of the loop then you want to await those to ensure they complete before processing the next line.
If you want to ensure that your "Method" finish completes before it is called again, you want to ensure that the call to Method() is awaited or otherwise Waited.
You don't normally add things like Task.Delay in code to force it to delay until other code has executed. That would be used for testing out waiting behaviour. Code should take only as long as it needs to, and when it comes to asynchronous code, as long as it is awaited properly, there is no need to put in things like delays.
Asynchronous code allows your code, or processes around your code to manage a degree of parallelism. It is not a silver bullet to solve problems like "my code is taking too long", and you do need to be very careful with parallelism when it comes to references to classes that are not thread safe. (I.e. EF DbContexts)
To avoid confusion, you should also always suffix your async methods with "Async" to make it crystal clear they are asynchronous and should be awaited. I.e. public Task MethodAsync().
So in summary,
Remove Task.Delay().
If your loop makes calls to async calls, await them. Synchronous calls will be done sequentially so the loop will already wait for them to complete.
Ensure that if the caller of MethodAsync is async itself, the call to MethodAsync should be awaited. If the caller of MethodAsync is synchronous and you cannot use await, then Wait the returned Task. Just don't, this is a rabbit hole you don't want to look down, make a synchronous version of the code.

Is it wrong to use ManualResetEvent with async code? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am looking for the best practices to synchronize Tasks (not even sure that this is semantically right, I should probably say synchronize Threads with async code).
Take the following code:
Task.Run(async () => await lib.WaitAsync());
Task.Run(async () => await lib.WaitAsync());
Task.Run(async () => await lib.WaitAsync());
// Synchronize all waiters
lib.Release();
// All Tasks shall be completed
When working with Threads, I used to do that with ManualResetEvent. So my first (simplified) approach would be:
Task WaitAsync()
{
await Task.Run(() => manualResetEvent.WaitOne());
}
void Release()
{
manualResetEvent.Set();
}
Now I see that people have made their own implementation of async ManualResetEvent.
What is wrong with the original approach and why would someone prefer an async implementation ?
Is it because of the cancellation ? The exceptions unwrapping/handling ?
And more generally, is there any disadvantage when using the regular Thread synchronization objects (Mutex, Semaphore, ...) with async code ?
Thank you
An asynchronous Task may use multiple threads when progressing from one internal asynchronous operation to the next, and may not utilize any thread at all for most of its lifetime. This is desired, because it promotes scalability. Blocking threads is a waste of resources. And all threading synchronization primitives (Mutex, Semaphore, WaitHandle etc) are doing just that, they block threads.
On the contrary no threads are blocked when throttling asynchronous operations with SemaphoreSlim.WaitAsync, which is the only available built-in mechanism for blocking tasks asynchronously AFAIK.

Difference Between 2 Ways to Start Async Task Without Waiting in ASP.NET MVC [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
An asynchronous method like below should be executed without waiting in a ASP.NET MVC website.
public async Task DoStaff()
{
// business logic here
}
And we found two solutions to accomplish this and both work on our testbed:
Solution 1:
public void DoStaffWrapper()
{
DoStaff();
// clean up
}
public ActionResult Caller()
{
DoStaffWrapper();
// return blah blah blah;
}
Solution 2:
public async Task DoStaffWrapperAsync()
{
await DoStaff();
// clean up
}
public ActionResult Caller()
{
Task.Run(() => DoStaffWrapperAsync());
// return blah blah blah;
}
So what is the difference between them? which is the better and why? Any benefits?
Unless you have precise control over the lifecycle of your IIS pool (or unless you're not actually running on IIS), you should use QueueBackgroundWorkItem to launch your fire-and-forget tasks. It makes sure the runtime is able to track them, and won't terminate prematurely the process.
HostingEnvironment.QueueBackgroundWorkItem(_ => DoStaff());
If for some reason you don't want to use this method, or don't need it, there's an important difference between the two ways of calling the async method:
DoStaff() will run synchronously on the current thread until an await statement is found, then it will yield control over the thread (and whatever you have after DoStaff will be able to execute. Also, the mehtod will execute inside of ASP.NET's synchronization context, so you will run into trouble if you're not using .ConfigureAwait(false) whenever awaiting calls inside of it.
Task.Run(() => DoStaffWrapperAsync()) will entirely run asynchronously, and in a separate context (so you won't run into the aforementioned issue).
To put it simple, take the following method:
public Task DoStaff()
{
Thread.Sleep(1000);
await AnotherMethodAsync();
Thread.Sleep(1000);
}
If you call DoStaff, the call will be blocking for one second. If you call Task.Run(() => DoStaff()), the call will return immediately. But if there's no significant amount of work before the first await, then you'll be jumping to a new thread for no practical gain.

C# Prevent async task from being run again before finishing [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I cant seem to find the information that im looking for in the documentation and could use a second pair of eyes. I would like to do this without testing; only a visual examination and theory discussion.
My draft attempt sets a bool which will only allow an async method to be run if the returned task sets its value to Task.IsCompleted. My question is, will this code do what I assume it will and if not, what is an alternative that will perform only a single call at a time? (assuming the infinite loop and async task remain unchanged)
You may fairly assume that RunAsync() is an asynchronous method, denoted by the async keyword, containing an awaitable task which returns a Task instance.
bool asyncOutputCallAllowed = true;
while (true)
{
if (asyncOutputCallAllowed)
{
asyncOutputCallAllowed = false;
asyncOutputCallAllowed = RunAsync().IsCompleted;
}
}
I am guessing that you are trying to do the following: make an async call, keep looping and doing other stuff while also waiting for async-task to finish, and then start a new async task when the previous one finishes. If so, then you probably want something along the following lines:
Task activeOperation = null;
while (true)
{
if (activeOperation == null)
{
// No async operation in progress. Start a new one.
activeOperation = RunAsync();
}
else if (activeOperation.IsCompleted)
{
// Do something with the result.
// Clear active operation so that we get a new one
// in the next iteration.
activeOperation = null;
}
// Do some other stuff
}
Depending on your exact algorithm, you might want to start the new task in the same iteration in which the previous one finishes. That is just a small tweak of the above.
If you are not doing anything else in the loop except wait for the async-task, then you can get rid of the loop entirely and use a continuation instead (see ContinueWith).

Is waiting a thread to be alive with a loop good practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Do we really have to do this?
// Loop until worker thread activates.
while (!workerThread.IsAlive);
Wouldn't it be better to just use a ManualResetEvent (or else) at the start of the thread's function?
Edit 1:
Perhaps in the MSDN example context it would be "appropiate":
// Start the worker thread.
workerThread.Start();
Console.WriteLine("main thread: Starting worker thread...");
 
// Loop until worker thread activates.
while (!workerThread.IsAlive);
Otherwise this just feels like an awful code smell.
Source: http://msdn.microsoft.com/en-US/library/7a2f3ay4(v=vs.80).aspx
Please ignore the MSDN example, it's horrible and senseless. In particular, the spin waiting on IsAlive makes no sense because there is no way for the thread to be terminated "before it has a chance to execute", as the MSDN says. The thread is free not to check the flag you set for requesting termination until it is ready. Spin-waiting on IsAlive never makes sense -- use Thread.Join() to wait on exit, and events (or monitors) to wait for other states.
Good practice is to use the Task-based Asynchronous Pattern (TAP)
Use Task.Run like this,
public async Task DoStuff(CancellationToken token)
{
await Task.Run(
() => Console.WriteLine("Stuff"),
token)
}
or just,
Task.Run(() => Console.WriteLine("Stuff")).Wait();
There is no built-in infrastructure to wait for thread to start, because in most cases this should not be important. We must wait for thread to finish always, but let it do about its business in the mean time.
You probably even don't want to wait for thread to start. You probably want for thread to activate some of its functionality, and in general case there could me more than one of those functionalities. No built-in system can cater for this, so you have to roll your own synchronization.
Just have some event that is created when the thread is created, but is raised in the thread run code. When you create and start the thread wait on this event and that's it.

Categories