How to call a method asynchronously in c# - c#

I have a method public void foo(){} which in turn calls another method public void fooBL(){}
which is in the BusinessLogic layer. fooBL() then calls another method fooDAL() which is in the DataAccessLayer. I want to call foo() asynchronously on a button click event. I'm using .NET4.0.

It depends on what your goal is.
The simplest way to call foo asynchronous is:
Task t = new Task.Factory.StartNew(foo);

You can use thread to run method asynchronously. Below is an example:
Thread t = new Thread(new ThreadStart(foo));
t.Start();
I hope it helps you. :)

You can wrap anything in Task.Run to run it via the default scheduler (the ThreadPool):
Task.Run(() => {
yourMethodCallHere();
});
You should avoid the use of StartNew if you are unaware of how it works. You could introduce potential bugs as it captures the currently executing TaskScheduler instance and you will no doubt hit "cross-thread" exceptions when dealing with UI elements (or other, much more subtle bugs).

Related

Start in a new thread in the same method

I'm beginner in the usage of threads and in the examples that I've seen (as here and here) a new thread must be assigned to a method. But, is there a way of making that inside the method? I'm looking for something like this:
public void MyMethod()
{
//Start new thread that affects only this method
//Do stuff
//More stuff
}
Thank you.
You can start anonymous method or lambda if you don't want to create separate method.
Simplest way:
Task.Run(()=>{
// Your new thread code
});
Be aware that this creates closure and parent method variables you use in your thread will not be disposed until your thread is done. Also it's not a good practice to start a long running threads like this, because it uses thread pool.
So in this case you can do something like in the code below, or use more verbose syntax for creating tasks and specify TaskCreationOptions.LongRunning parameter.
new Thread((ThreadStart)delegate() {
// Your new thread code
}).Start();
You can put new Thread object into variable to control it later.

async await and shared objects

I'm using the async / await pattern to perform some CPU heavy operations on an object (my method is awaitable), which works as supposed without blocking the UI thread.
However, when i pass the object as a parameter to the ctor of a new window (the new window is a logging window that needs access to the processed object), my UI thread blocks (which I kinda understand why).
to get around this I could wrap the execution of the calculation in a
Task.Run(async () => { await _myObject.PerformCalculations(); });
and then simply call
var logWindow = new LogWindow(_myObject);
logWindow.Show();
This works (of course) but i have a lot of dispatcher calls when the object raises events, which I wouldn't have to deal with if I could do without the Task.Run call.
So, my question is, can I somehow do without the Task.Run call and still pass the object to the logging window without blocking my UI thread?
EDIT
I'm sorry for the stripped down example, I actually intended to make the question as simple as possible to understand and failed miserably.
In a more general way: I have an object that raises events on certain conditions. When an event is raised, I want to perform updates on the UI. An event always fires from the thread that was created using Task.Run(...). Hence, dispatcher calls to the UI thread. So, I want to perform the calculations using async / await (already works) and pass the object to my logging window (blocks).
When I use Task.Run, everything works of course, but wherever I subscribe to an event of the object from the UI thread I have to use dispatcher calls to the UI thread, because the event fires from the thread that Task.Run created. These dispatcher calls I would like to avoid. In fact, if I wouldn't pass the object to the logging window, and call the Show() method, the UI thread wouldn't block and everything would work as supposed. No dispatcher calls needed in the event handlers.
It's kind of hard to get a clear picture of your situation. But it looks to me like you could do with some refactoring.
Consider PerformCalculations: this is a method returning Task (thus advertising itself as async-friendly) that does heavy CPU usage (thus not actually being async-friendly). The first thing I would look at is dividing up the logic in PerformCalculations so that the CPU-bound portions use their own Task.Run, leaving PerformCalcuations as an async method that doesn't (directly) hit the CPU:
public async Task PerformCalculationsAsync()
{
while (...)
{
await Task.Run(<next calculations>);
RaiseEvent();
}
}
The point of this refactoring is to divide the CPU code in Task.Run from the UI-ish code raising events. Also consider using the standard IProgress<T> approach if your events are logically progress updates or if this kind of refactoring would be too difficult for your code; IProgress<T>.Report can be called from any thread.
You may also find my posts on async constructors and async properties (particularly the data-binding section) to be helpful.
// awaitable as well - await this in another async void/Task method (e.g. commanding)
public async Task MyAsyncProcess()
{
await _myObject.PerformCalculations();
var logWindow = new LogWindow(_myObject);
}
Task.Run() executes an asynchronous method synchronously, so in this case you pretty much lack of use of the async/await pattern. Make the method where you execute your code async as well and await it somewhere else. Or alternatively use some FireAndForget logic.

Is there a way to signal a System.Threading.Tasks.Task complete?

I have a library that is a complicated arbiter of many network connections. Each method of it's primary object takes a delegate, which is called when the network responds to a given request.
I want to translate my library to use the new .NET 4.5 "async/await" pattern; this would require me to return a "Task" object, which would signal to the user that the asynchronous part of the call is complete. Creating this object requires a function for the task to represent - As far as my understanding, it is essentially a lightweight thread.
This doesn't really fit the design of my library - I would like the task to behave more like an event, and directly signal to the user that their request has completed, rather then representing a function. Is this possible? Should i avoid abusing the "async/await" pattern in this way?
I don't know if I'm wording this very well, I hope you understand my meaning. Thank you for any help.
As far as my understanding, it is essentially a lightweight thread.
No, that's not really true. I can be true, under certain circumstances, but that's just one usage of Task. You can start a thread by passing it a delegate, and having it execute it (usually asynchronously, possibly synchronously, and by default using the thread pool).
Another way of using threads is through the use of a TaskCompletionSource. When you do that the task is (potentially) not creating any threads, using the thread pool, or anything along those lines. One common usage of this model is converting an event-based API to a Task-based API:
Let's assume, just because it's a common example, that we want to have a Task that will be completed when a From that we have is closed. There is already a FormClosed event that fires when that event occurs:
public static Task WhenClosed(this Form form)
{
var tcs = new TaskCompletionSource<object>();
form.FormClosing += (_, args) =>
{
tcs.SetResult(null);
};
return tcs.Task;
}
We create a TaskCompletionSource, add a handler to the event in question, in that handler we signal the completion of the task, and the TaskCompletionSource provides us with a Task to return to the caller. This Task will not have resulted in any new threads being created, it won't use the thread pool, or anything like that.
You can have a Task/Event based model using this construct that appears quite asynchronous, but only using a single thread to do all work (the UI thread).
In general, anytime you want to have a Task that represents something other than the execution of a function you'll want to consider using a TaskCompletionSource. It's usually the appropriate conceptual way to approach the problem, other than possibly using one of the existing TPL methods, such as WhenAll, WhenAny, etc.
Should I avoid abusing the "async/await" pattern in this way?
No, because it's not abuse. It's a perfectly appropriate use of Task constructs, as well as async/await. Consider, for example, the code that you can write using the helper method that I have above:
private async void button1_Click(object sender, EventArgs e)
{
Form2 popup = new Form2();
this.Hide();
popup.Show();
await popup.WhenClosed();
this.Show();
}
This code now works just like it reads; create a new form, hide myself, show the popup, wait until the popup is closed, and then show myself again. However, since it's not a blocking wait the UI thread isn't blocked. We also don't need to bother with events; adding handlers, dealing with multiple contexts; moving our logic around, or any of it. (All of that happens, it's just hidden from us.)
I want to translate my library to use the new .NET 4.5 "async/await" pattern; this would require me to return a "Task" object, which would signal to the user that the asynchronous part of the call is complete.
Well, not really - you can return anything which implements the awaitable pattern - but a Task is the simplest way of doing this.
This doesn't really fit the design of my library - I would like the task to behave more like an event, and directly signal to the user that their request has completed, rather then representing a function.
You can call Task.ContinueWith to act as a "handler" to execute when the task completes. Indeed, that's what TaskAwaiter does under the hood.
Your question isn't terribly clear to be honest, but if you really want to create a Task which you can then force to completion whenever you like, I suspect you just want TaskCompletionSource<TResult> - you call the SetResult, SetCanceled or SetException methods to indicate the appropriate kind of completion. (Or you can call the TrySet... versions.) Use the Task property to return a task to whatever needs it.

Is this a proper way of calling synchronous methods asynchronously?

I was using code like this:
handler.Invoke(sender, e);
But the problem with that code is that it is synchronous and all it really does is update the GUI. It is not necessary for the server to wait for it to complete so it should be made asynchronous.
I don't really want to use BeginInvoke and EndInvoke because a callback method is not necessary in this case.
Is this a suitable alternative?
Task.Factory.StartNew(() => handler.Invoke(sender, e));
The way you did it is fine, another way to do this that works on .NET 3.5 is using the ThreadPool class instead
ThreadPool.QueueUserWorkItem(new WaitCallback((a) => handler.Invoke(sender, e)))
Also if handler happens to be a derived from control, you are allowed to call BeginInvoke without a corresponding EndInvoke.
Calls to GUI are special in that they must always be done from the GUI thread. In your own words, handler.Invoke(sender, e) "updates the GUI", yet it is (probably) not executed from the GUI thread, so it not OK in its current form.
In WinForms, you'll need to wrap your task delegate into Control.Invoke (or forget about tasks and just use Control.BeginInvoke).
If WPF, you can wrap your task delegate into Dispatcher.Invoke (or just use Dispatcher.BeginInvoke without a task).
I'm not familiar with C# 4's Task class, but I know BeginInvoke works just fine without EndInvoke. I sometimes write code like this:
handler.BeginInvoke(sender, e, null, null);
Edit: I was mistaken. While EndInvoke is not necessary to cause the code to execute on a new thread, the documentation clearly states that EndInvoke is important.

Is BeginInvoke/EndInvoke good practice for invoking on main thread?

Is it good practice to invoke delegate for MainForm thread - this way?:
Txt.MainForm.EndInvoke(
Txt.MainForm.BeginInvoke(
new MethodInvoker(delegate()
{ // code here }
)));
No - because if you're calling EndInvoke, that will block until the delegate has completed. If you want that behaviour, just use Invoke instead.
To put it another way: if you're trying to do something other than blocking until your (presumably UI-modifying) delegate has executed in the UI thread, you should explain what that something is. If there isn't anything else, then Invoke will give you simpler code.
It doesn't make a lot of sense as the code fires up an asynchronous call and then immediately waits for the call to finish. I.e. you end up waiting on the calling thread.
Not considering the thing that other mentioned (I believe this EndInvoke - BeginInvoke chain is just an example usage of delegate): Using delegates is 100% OK. If this is the only usage of the delegate body, there's no need to define it as a named method. It is cleaner in the code and there's no need to jump through the file. Consider using newer syntax for delegates:
new MethodInvoker(() => { // code here })

Categories

Resources