I want to update the information in the database asynchronously, what is the difference between the following implementation, both are asynchronous?
Which one is better to use?
new System.Threading.Thread(() => {
userModel.Update(); //update the database
}).Start();
internal async void ProcessMessageReceived(UserModel userModel) {
userModel.Update();
}
Your first implementation is using a new thread, while the second seems to be using the TPL. We need to see the implementation of the Update method to be completely sure, I guess its returning a Task?
Using the TPL is normally more efficient than spawning your own threads.
TPL tasks use the thread pool and allow the re usability of Tasks which can provide extra performance advantages.
Related
We have a multi threaded application that uses synchronous methods. Is there a performance difference between the two methods?
public void RunSleep()
{
Thread.Sleep(3000);
}
public void RunTask()
{
var task = Task.Run(() =>
{
Thread.Sleep(3000);
});
task.Wait();
}
Thread.Sleep is supposed to symbolise an HTTP request.
While I understand that refactoring it to be an asynchronous method would be optimal, is there a benefit to using the second version?
EDIT: to specify, my question was if wrapping a long running and synchronous method in a task results in more efficient multi threading, based on this thread this thread.
Relevant quote:
Use Thread.Sleep when you want to block the current thread.
and
Use Task.Delay when you want a logical delay without blocking the current thread.
Thread.Sleep is supposed to symbolise an HTTP request
In that case it would be a clever decision to stick with an asynchronous method because all HttpClient Methods are asynchronous
my question was if wrapping a long running and synchronous method in a task results in more efficient multi threading, based on this thread
I guess that would be a bad idea
For further reading, you can take a look at this nice article.
I understand that Task.Wait() blocks the thread all the same, all I get from using them is some overhead. Thank you for the answers and discussion.
Firstly I believe that the first time is just a condition to see this blocking more clearly. For next times, somehow it still blocks the UI slightly but not obvious like when not using async.
I can say that because I can see the difference between using that QueryAsync and a simple wrapping code with Task.Run(() => connection.Query<T>) which works fine and of course much better than QueryAsync (in UX).
The code is just simple like this:
public async Task<IEnumerable<Item>> LoadItemsAsync(){
using(var con = new OracleConnection(connectionString)){
var items = await con.QueryAsync<dynamic>("someQuery");
return items.Select(e => new Item { ... });
}
}
//in UI thread, load items like this:
var items = await LoadItemsAsync();
The code working fine (without blocking UI) is like this:
public async Task<IEnumerable<Item>> LoadItemsAsync(){
using(var con = new OracleConnection(connectionString)){
var items = await Task.Run(() => con.Query<dynamic>("someQuery"));
return items.Select(e => new Item { ... });
}
}
//in UI thread, load items like this:
var items = await LoadItemsAsync();
I know that Task.Run() is not actually async to the detail but at least it puts the whole work to another thread and makes the UI free from being blocked and frozen.
I guess this might be a bug in Dapper, please take sometime to test this. I'm not so sure how to exactly reproduce this, but if possible please try a Winforms project, a fairly large Oracle database and of course as I said you can see it the most obviously by the first time querying (so be sure to run the clearing-cache query against the Oracle server before each test).
Finally if you have some explanation and solution to this (of course without using Task.Run), please share in your answer.
With async await you can free and use UI thread only during execution of a truly asynchronous operation (for example, asynchronous IO or a task delegated to a thread pool thread). In your case, methods that utilze Oracle driver (ODP.NET) are not truly asynchronous. See Can the Oracle Managed Driver use async/wait properly? discussion on Stack Overflow.
If you want to offload work from a UI thread to increase responsiveness, simply use Task.Run():
var items = await Task.Run(() => LoadItems());
Use of any other mechanism such as Task.ConfigureAwait(false), or synchronization context replacement combined with Task.Yield() will result in use of an additional thread pool thread too, but it will free UI thread later.
For more information check:
Should I expose asynchronous wrappers for synchronous methods? article by Stephen Toub
Async/Await FAQ article by Stephen Toub
Task.Run Etiquette Examples: Even in the Complex Case, Don't Use Task.Run in the Implementation article by Stephen Cleary
I think what you're seeing here might be due to a bug in .net, rather than dapper. The bug is:
https://github.com/Microsoft/dotnet/issues/579
The issue you're maybe seeing is that dapper.Query will internally call SqlDataReader.ReadAsync which can sometimes result in sync/blocking behaviour. This bug is due to be fixed in .net 4.7.3 but the latest pre-release builds still seem to contain this issue.
Also see: How do I make SqlDataReader.ReadAsync() run asynchronously?
What would be an appropriate way to re-write my SlowMethodAsync async method, which executes a long running task, that can be awaited, but without using Task.Run?
I can do it with Task.Run as following:
public async Task SlowMethodAsync()
{
await Task.Run(() => SlowMethod());
}
public void SlowMethod()
{
//heavy math calculation process takes place here
}
The code, as it shown above, will spawn a new thread from a thread-pool. If it can be done differently, will it run on the invocation thread, and block it any way, as the SlowMethod content is a solid chunk of math processing without any sort of yielding and time-slice surrendering.
Just to clarify that I need my method to stay asynchronous, as it unblocks my UI thread. Just looking for another possible way to do that in a different way to how it's currently done, while keeping async method signature.
async methods are meant for asynchronous operations. They enable not blocking threads for non-CPU-bound work. If your SlowMethod has any IO-bound operations which are currently executed synchronously (e.g. Stream.Read or Socket.Send) you can exchange these for async ones and await them in your async method.
In your case (math processing) the code's probably mostly CPU-bound, so other than offloading the work to a ThreadPool thread (using Task.Run) there's no reason to use async as all. Keep SlowMethod as it is and it will run on the calling thread.
Regarding your update: You definitely want to use Task.Run (or one of the Task.Factory.StartNew overloads) to offload your work to a different thread.
Actually, for your specific case, you should use
await Task.Factory.StartNew(() => SlowMethod(), TaskCreationOptions.LongRunning)
which will allow the scheduler to run your synchronous task in the appropriate place (probably in a new thread) so it doesn't gum up the ThreadPool (which isn't really designed for CPU heavy workloads).
Wouldn't it be better just to call SlowMethod synchronously? What are you gaining by awaiting it?
I have a method with 3 parameters on which I would like to create for it a thread. I know how to create a thread for a method without any paremeters and with object type parameter. The method header is:
public void LoadData(DataGridView d, RadioButton rb1, RadioButton rb2){
//}
In addition to Tzah answer, you do not mention the thread life time and management. This is a good place to think about it - As long as you write high quality code..
If you use thread from threadpool with 3 params and more, using my previous answer: C# - ThreadPool QueueUserWorkItem Use?
If you are using .Net 4.0+ consider using Tasks
You can use Lambda Expression like this:
new Thread(() => LoadData(var1, var2, var3)).Start();
or
Thread T1 = new Thread(() => LoadData(var1, var2, var3));
T1.Start();
As Tzah's answer will definitely work, the recommanded way of using threads in the .NET Framework now resides with the Task Parallel Library. The TPL provided an abstraction over the ThreadPool, which manages a pool of threads for us to use instead of creating and destroying, which has a non-neglectibale cost. They may not be suitable for all sorts of offload work (like very long running cpu consuming tasks), but they will definitely cover most cases.
An example equivalent to your request using the TPL would be to use Task.Run:
Task task = Task.Run(() => LoadData(var1, var2, var3));
I am trying to better understand the Async and the Parallel options I have in C#. In the snippets below, I have included the 5 approaches I come across most. But I am not sure which to choose - or better yet, what criteria to consider when choosing:
Method 1: Task
(see http://msdn.microsoft.com/en-us/library/dd321439.aspx)
Calling StartNew is functionally equivalent to creating a Task using one of its constructors and then calling Start to schedule it for execution. However, unless creation and scheduling must be separated, StartNew is the recommended approach for both simplicity and performance.
TaskFactory's StartNew method should be the preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation and scheduling must be separated, the constructors may be used, and the task's Start method may then be used to schedule the task for execution at a later time.
// using System.Threading.Tasks.Task.Factory
void Do_1()
{
var _List = GetList();
_List.ForEach(i => Task.Factory.StartNew(_ => { DoSomething(i); }));
}
Method 2: QueueUserWorkItem
(see http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx)
You can queue as many thread pool requests as system memory allows. If there are more requests than thread pool threads, the additional requests remain queued until thread pool threads become available.
You can place data required by the queued method in the instance fields of the class in which the method is defined, or you can use the QueueUserWorkItem(WaitCallback, Object) overload that accepts an object containing the necessary data.
// using System.Threading.ThreadPool
void Do_2()
{
var _List = GetList();
var _Action = new WaitCallback((o) => { DoSomething(o); });
_List.ForEach(x => ThreadPool.QueueUserWorkItem(_Action));
}
Method 3: Parallel.Foreach
(see: http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx)
The Parallel class provides library-based data parallel replacements for common operations such as for loops, for each loops, and execution of a set of statements.
The body delegate is invoked once for each element in the source enumerable. It is provided with the current element as a parameter.
// using System.Threading.Tasks.Parallel
void Do_3()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
Parallel.ForEach(_List, _Action);
}
Method 4: IAsync.BeginInvoke
(see: http://msdn.microsoft.com/en-us/library/cc190824.aspx)
BeginInvoke is asynchronous; therefore, control returns immediately to the calling object after it is called.
// using IAsync.BeginInvoke()
void Do_4()
{
var _List = GetList();
var _Action = new Action<object>((o) => { DoSomething(o); });
_List.ForEach(x => _Action.BeginInvoke(x, null, null));
}
Method 5: BackgroundWorker
(see: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)
To set up for a background operation, add an event handler for the DoWork event. Call your time-consuming operation in this event handler. To start the operation, call RunWorkerAsync. To receive notifications of progress updates, handle the ProgressChanged event. To receive a notification when the operation is completed, handle the RunWorkerCompleted event.
// using System.ComponentModel.BackgroundWorker
void Do_5()
{
var _List = GetList();
using (BackgroundWorker _Worker = new BackgroundWorker())
{
_Worker.DoWork += (s, arg) =>
{
arg.Result = arg.Argument;
DoSomething(arg.Argument);
};
_Worker.RunWorkerCompleted += (s, arg) =>
{
_List.Remove(arg.Result);
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
};
if (_List.Any())
_Worker.RunWorkerAsync(_List[0]);
}
}
I suppose the obvious critieria would be:
Is any better than the other for performance?
Is any better than the other for error handling?
Is any better than the other for monitoring/feedback?
But, how do you choose?
Thanks in advance for your insights.
Going to take these in an arbitrary order:
BackgroundWorker (#5)
I like to use BackgroundWorker when I'm doing things with a UI. The advantage that it has is having the progress and completion events fire on the UI thread which means you don't get nasty exceptions when you try to change UI elements. It also has a nice built-in way of reporting progress. One disadvantage that this mode has is that if you have blocking calls (like web requests) in your work, you'll have a thread sitting around doing nothing while the work is happening. This is probably not a problem if you only think you'll have a handful of them though.
IAsyncResult/Begin/End (APM, #4)
This is a widespread and powerful but difficult model to use. Error handling is troublesome since you need to re-catch exceptions on the End call, and uncaught exceptions won't necessarily make it back to any relevant pieces of code that can handle it. This has the danger of permanently hanging requests in ASP.NET or just having errors mysteriously disappear in other applications. You also have to be vigilant about the CompletedSynchronously property. If you don't track and report this properly, the program can hang and leak resources. The flip side of this is that if you're running inside the context of another APM, you have to make sure that any async methods you call also report this value. That means doing another APM call or using a Task and casting it to an IAsyncResult to get at its CompletedSynchronously property.
There's also a lot of overhead in the signatures: You have to support an arbitrary object to pass through, make your own IAsyncResult implementation if you're writing an async method that supports polling and wait handles (even if you're only using the callback). By the way, you should only be using callback here. When you use the wait handle or poll IsCompleted, you're wasting a thread while the operation is pending.
Event-based Asynchronous Pattern (EAP)
One that was not on your list but I'll mention for the sake of completeness. It's a little bit friendlier than the APM. There are events instead of callbacks and there's less junk hanging onto the method signatures. Error handling is a little easier since it's saved and available in the callback rather than re-thrown. CompletedSynchronously is also not part of the API.
Tasks (#1)
Tasks are another friendly async API. Error handling is straightforward: the exception is always there for inspection on the callback and nobody cares about CompletedSynchronously. You can do dependencies and it's a great way to handle execution of multiple async tasks. You can even wrap APM or EAP (one type you missed) async methods in them. Another good thing about using tasks is your code doesn't care how the operation is implemented. It may block on a thread or be totally asynchronous but the consuming code doesn't care about this. You can also mix APM and EAP operations easily with Tasks.
Parallel.For methods (#3)
These are additional helpers on top of Tasks. They can do some of the work to create tasks for you and make your code more readable, if your async tasks are suited to run in a loop.
ThreadPool.QueueUserWorkItem (#2)
This is a low-level utility that's actually used by ASP.NET for all requests. It doesn't have any built-in error handling like tasks so you have to catch everything and pipe it back up to your app if you want to know about it. It's suitable for CPU-intensive work but you don't want to put any blocking calls on it, such as a synchronous web request. That's because as long as it runs, it's using up a thread.
async / await Keywords
New in .NET 4.5, these keywords let you write async code without explicit callbacks. You can await on a Task and any code below it will wait for that async operation to complete, without consuming a thread.
Your first, third and forth examples use the ThreadPool implicitly because by default Tasks are scheduled on the ThreadPool and the TPL extensions use the ThreadPool as well, the API simply hides some of the complexity see here and here. BackgroundWorkers are part of the ComponentModel namespace because they are meant for use in UI scenarios.
Reactive extensions is another upcoming library for handling asynchronous programming, especially when it comes to composition of asynchronous events and methods.
It's not native, however it's developed by Ms labs. It's available both for .NET 3.5 and .NET 4.0 and is essentially a collection of extension methods on the .NET 4.0 introduced IObservable<T> interface.
There are a lot of examples and tutorials on their main site, and I strongly recommend checking some of them out. The pattern might seem a bit odd at first (at least for .NET programmers), but well worth it, even if it's just grasping the new concept.
The real strength of reactive extensions (Rx.NET) is when you need to compose multiple asynchronous sources and events. All operators are designed with this in mind and handles the ugly parts of asynchrony for you.
Main site: http://msdn.microsoft.com/en-us/data/gg577609
Beginner's guide: http://msdn.microsoft.com/en-us/data/gg577611
Examples: http://rxwiki.wikidot.com/101samples
That said, the best async pattern probably depends on what situation you're in. Some are better (simpler) for simpler stuff and some are more extensible and easier to handle when it comes to more complex scenarios. I cannot speak for all the ones you're mentioning though.
The last one is the best for 2,3 at least. It has built-in methods/properties for this.
Other variants are almost the same, just different versions/convinient wrappers