I'm working on a wrapping library for a robot controller, that mostly relies on P/Invoke calls.
However, a lot of the functionality for the robot, such as homing, or movement, takes quite a while, and do thread locks while running.
So I'm wondering how I can wrap the functionality in a async manner, so the calls don't block my UI thread. My idea so far is to use Tasks, but I'm not really sure it's the right approach.
public Task<bool> HomeAsync(Axis axis, CancellationToken token)
{
return Task.Factory.StartNew(() => Home(axis), token);
}
Most of the MSDN articles on the Async model in .NET as of right now, mostly is relaying on libraries already having Async functionality (such as File.BeginRead and so on). But I can't seem to find much information on how to actually write the async functionality in the first place.
After some great discussion, I think something like this will be the golden middleway.
public void HomeAsync(Axis axis, Action<bool> callback)
{
Task.Factory
.StartNew(() => Home(axis))
.ContinueWith(task => callback(task.Result));
}
This is using the best of both worlds, I think.
Have you ever tried async delegates? I believe there is nothing simpler than it.
If your thread-blocking method is void Home(Axis) you have first to define a delegate type, ie. delegate void HomeDelegate(Axis ax), then use the BeginInvoke method of a new instance of HomeDelegate pointing to the address of Home method.
[DllImport[...]] //PInvoke
void Home(Axis x);
delegate void HomeDelegate(Axis x);
void main()
{
HomeDelegate d = new HomeDelegate(Home);
IAsyncResult ia = d.BeginInvoke(axis, null, null);
[...]
d.EndInvoke(ia);
}
Please bear in mind that using the EndInvoke somewhere (blocking the thread until the method is finally over, maybe in conjunction with polling of IAsyncResult.Completed property) is very useful to check if your async task has really been completed. You might not want your robot to open its arm and leave a glass until the glass is over the table, you know ;-)
My first reaction is that this is not something you should do in the library. The primary reason is that the way you implement such a system may depend on the type of interface you are building upon the library.
That said, you have basically two choices. First is the IAsyncResult. A good description of this can be found at http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html.
The second option is to create commands with callback events. The user creates a command class and sets a callback on that. Then, you schedule the command to a ThreadPool and after the command has been executed, you raise that event.
Older interfaces of the .NET framework primarily implemented the IAsyncResult approach, where newer interfaces tend to implement the event callback approach.
Related
I'm in a situation where we have some code that is run by user input (button click), that runs through a series of function calls and result in generating some data (which is a quite heavy operation, several minutes). We'd like to use Async for this so that it doesn't lock up the UI while we're doing this operation.
But at the same time we also have a requirement that the functions will also be available through an API which preferably should be synchronous.
Visualization/Example (pseudo-code):
public async void Button_Click() // from UI context
{
await instanceOfClassA.FuncA();
// some code
}
public async Task ClassA.FuncA()
{
await instanceOfClassB.FuncB()
// some code
}
public async Task ClassB.FuncB()
{
await instanceOfClassC.SomeHeavyFunc()
// some code
}
public async Task ClassC.SomeHeavyFunc()
{
// some heavy calculations
}
// Also need to provide a public synchronous API function
public void SomeClass.SynchronousAPIFunc()
{
// need to call differentInstanceOfClassB.FuncB()
}
Is there a way to make it so that the public API function does the waiting for the async operation internally?
EDIT:
In this post, user Rachel provides two answers to the question. Both seem interesting, though I'm unsure which one would offer the least amount of risk/side effects.
EDIT2:
I should note that we're using .NET v4.6.1.
Thanks in advance.
The problem with making "synchronous" versions of your methods that just call the asynchronous versions is that it can cause deadlocks, especially if the person calling this code is not aware that this is what is happening.
If you really want to make synchronous versions, then follow Microsoft's lead and write completely new methods that do not use any asynchronous code. For example, the implementation for File.ReadAllLines() doesn't use any of the same code as File.ReadAllLinesAsync().
If you don't want to do that, then just don't provide synchronous versions of your methods. Let the caller make the decision on how to deal with it. If they want to block synchronously on it, then they can mitigate the risk of deadlock.
But at the same time we also have a requirement that the functions will also be available through an API which preferably should be synchronous.
If you have the need to expose both a synchronous and asynchronous API, I recommend the boolean argument hack. This looks like:
public Task<T> FuncBAsync() => FuncBAsync(sync: false);
public T FuncB() => FuncBAsync(sync: true).GetAwaiter().GetResult();
public async Task<T> FuncBAsync(bool sync)
{
// Note: is `sync` is `true`, this method ***must*** return a completed task.
...
}
Is there a way to make it so that the public API function does the waiting for the async operation internally?
I do not recommend using direct blocking (e.g., GetAwaiter().GetResult()), as the straightforward implementation will lead to deadlocks.
EDIT: In this post, user Rachel provides two answers to the question.
I strongly recommend against using that solution. It uses a nested message loop with a custom SynchronizationContext, but doesn't do COM pumping. This can cause problems particularly if called from a UI thread. Even if the pumping isn't a problem, this solution can cause unexpected re-entrancy, which is a source of countless, extremely subtle, and difficult-to-find bugs.
You can utilize .GetAwaiter().GetResult()
as per your example, it would look like:
public void SomeClass.SynchronousAPIFunc()
{
// need to call differentInstanceOfClassB.FuncB()
ClassB.FuncB().GetAwaiter().GetResult();
}
Also, a good reference on when to not use the above can be found at Dont Block on Async Code
I have a large scale C# solution with 40-ish modules.
I'm trying to convert a service used solution-wide from synchronous to asynchronous.
the problem is I can't find a way to do so without changing the signature of the method.
I've tried wrapping said asynchronous desired operation with Task but that requires changing the method signature.
I've tried changing the caller to block itself while the method is operating but that screwed my system pretty good because it's a very long calling-chain and changing each of the members in the chain to block itself is a serious issue.
public SomeClass Foo()
{
// Synchronous Code
}
Turn this into:
public SomeClass Foo()
{
//Asynchronous code
}
whilst all callers stay the same
public void DifferentModule()
{
var class = Foo();
}
Any implementation that fundamentally changes something from sync to async is going to involve a signature change. Any other approach is simply not going to work well. Fundamentally: async and sync demand different APIs, which means: different signatures. This is unavoidable, and frankly "How to convert synchronous method to asynchronous without changing it's signature?" is an unsolvable problem (and more probably: the wrong question). I'm sorry if it seems like I'm not answering the question there, but... sometimes the answer is "you can't, and anyone who says you can is tempting you down a very bad path".
In the async/Task<T> sense, the most common way to do this without breaking compatibility is to add a new / separate method, so you have
SomeReturnType Foo();
and
Task<SomeReturnType> FooAsync(); // or ValueTask<T> if often actually synchoronous
nothing that Foo and FooAsync here probably have similar but different implementations - one designed to exploit async, one that works purely synchronously. It is not a good idea to spoof one by calling the other - both "sync over async" (the synchronous version calling the async version) and "async over sync" (the async version calling the sync version) are anti-patterns, and should be avoided (the first is much more harmful than the second).
If you really don't want to do this, you could also do things like adding a FooCompleted callback event (or similar), but : this is still fundamentally a signature change, and the caller will still have to use the API differently. By the time you've done that - you might as well have made it easy for the consumer by adding the Task<T> API instead.
The common pattern is to add an Async to the method name and wrap the return type in a Task. So:
public SomeClass Foo()
{
// Synchronous Code
}
becomes:
public Task<SomeClass> FooAsync()
{
// Asynchronous Code
}
You'll end up with two versions of the method, but it will allow you to gradually migrate your code over to the async approach, and it won't break the existing code whilst you're doing the migration.
If you desperately need to do this, it can be achieved by wrapping the Synchronous code that needs to become Asynchronous in a Task this can be done like this:
public SomeClass Foo()
{
Task t = Task.Run(() =>
{
// Do stuff, code in here will run asynchronously
}
t.Wait();
// or if you need a return value: var result = t.Wait();
return someClass;
// or return result
}
Code you write inside the Task.Run(() => ...) will run asynchronously
Short explanation: with Task t = Task.Run(() => ...) we start a new Task, the "weird" parameter is a Lambda expression, basically we're passing a anonymous Method into the Run method which will get executed by the Task
We then wait for the task to finish with t.Wait();. The Wait method can return a value, you can return a value from an anonymous method just like from any method, with the return keyword
Note: This can, but should not be done. See Sean's answer for more
I've been reading about asynchronous methods, specifically in C# with the new async/await keywords, and despite much reading and perusing this forum, I still am convinced that async requires multithreading. Please explain what I am misunderstanding!
I understand that you can write an async method without spawning a background thread. Super basic example:
async System.Threading.Tasks.Task<int> GetZeroAsync()
{
return 0;
}
But of course, this method is completely useless to be marked as async because, well, it isn't asynchronous. I also get a compiler warning about the method lacking an "await" operator, as expected. Okay, so what can we await? I can await something like Task.Run(), but that defeats the point, because I'm now using multithreading. Any other example I've found online tries to prove that you don't need multithreading by simply doing something like so:
async System.Threading.Tasks.Task<int> MyMethodAsync()
{
return await CallAnotherAsyncMethod();
}
Maybe I'm misunderstanding this, but all it proves to me is that I'm not the one who starts the multithreaded task, but I'm just calling another method that does. Since CallAnotherAsyncMethod() is also an async method, it must follow the exact same rules, right?. I can't have every async method just await another async sub-method forever, at some point it must stop unless you want infinite recursion.
The way I currently understand it, and I know this is wrong, is that async doesn't use multithreading, but it does require it, otherwise it's just a synchronous method lying to you.
So here's what might help. If async truly does not require multithreading, the following situation must be producible, I just can't find a way to do it. Can somebody create an example of a method that follows these rules:
Asynchronous.
Actually runs asynchronously.
Doesn't use any multithreading like calling Task.Run() or using a BackgroundWorker etc.
Doesn't call any other Async methods (unless you can also prove that this method follows these rules too).
Doesn't call any methods of the Task class like Task.Delay() (unless you can also prove that this method follows these rules too).
Any help or clarification would be really helpful! I feel like an idiot for not understanding this topic.
The easiest example of an async operation that does not use any kind of threads is waiting for a event to happen.
Create a UI app with your framework of choice and have two buttons, one called PrimeButton and one called RunButton
private TaskCompletionSource<object> _event = new TaskCompletionSource<object>();
//You are only allowed to do async void if you are writing a event handler!
public async void PrimeButton_OnClick(object sender, EventArgs e)
{
//I moved the code in to Example() so the async void would not be a distraction.
await Example();
}
public async Task Example()
{
await _event.Task;
MessageBox.Show("Run Clicked");
}
public async void RunButton_OnClick(object sender, EventArgs e)
{
_event.SetResult(null);
}
The await will wait till you click the 2nd button before it allows the code to continue and show the message box. No extra threads where involved at all here, all work was done using only the UI thread.
All a Task is, is a object that represents "something that will be finished at some point in the future". That something could be waiting for a background thread to complete that was started by a Task.Run or it could be waiting for a function to be called like the .SetResult( on the TaskCompletionSource<T>, or it could be waiting for some kind of disk or network IO to finish and be read in to a buffer by the OS (however internally this is usually implemented via a internal TaskCompletionSource<T> buried inside of the ReadAsync() function, so it is just a repeat of the last example with a wrapper around it)
If I call RunSynchronously() on a Task in C#, will this lead to asynchronous calls further down the rabbit hole to be run synchronously as well?
Let's say I have a method named UpdateAsync(). Inside this method another asynchronous call is made to DoSomethingAsync() and inside this again we find DoSomethingElseAsync(), will calling RunSynchronously() on 'UpdateAsync()' lead to RunSynchronously() also indirectly being called on DoSomethingAsync()?
The reason for my question:
I have a situation where I "need" to call an asynchronous method (UpdateAsync()) inside a catch-block and wonder if calling this with RunSynchronously() is safe. The documentation is quite clear on the fact that you can't await inside a catch-block. (Strictly speaking I could use a boolean inside the catch-block and call UpdateAsync() after the try-catch, but that feels rather dirty). Sorry about the dual question, but as you probably understand I don't quite know how to phrase it and do not have a really good understanding of this field.
(Edit:
I don't know how to find out if a method was called asynchronously. How would you write a unit test for this? Is it possible to log it somehow?)
I "need" to call an asynchronous method and wonder if calling this with RunSynchronously() is safe
There are two kinds of Tasks: code-based* Tasks (you can create those by using the Task constructor or Task.Factory.StartNew()) and promise-style Tasks (you can create them manually by using TaskCompletionSource or by writing an async method).
And the only Tasks that you can start by calling Start() or RunSynchronously() are unstarted code-based Tasks. Since async methods return promise-style Tasks (or possibly already started code-based Tasks), calling RunSynchronously() on them is not valid and will result in an exception.
So, to actually answer your question: what you're asking isn't possible, so it doesn't make sense to ask whether it's safe.
* This is not an official name, I don't know if there is one.
It's hard to predict without code how it will execute nested async methods.
You can log on each async method Thread.CurrentThread.ManagedThreadId property and compare id with other thread IDs that you have. When they vary, then your async methods are in multithreaded executtion
Or try to use Concurrency Visualizer from Visual Studio, Analyze menu. With Task class instances and even with C#5 async syntax there is no way to get to know that you are executing in parallel or another thread.
I think I'll be contradicting #svick's answer, but I feel the OP question is valid, because an async method's "promised" (to use Svick's terminology) Task can be obtained, but not started, thus allowing to do Task.RunSynchronously().
static void Main(string[] args)
{
...
//obtain a Task that's not started
var t = new Task<int>((ob) => GetIntAsync((string)ob).Result, someString);
...
}
static async Task<int> GetIntAsync(string callerThreadId)
{
...
Having said that, the answer is: No, the RunSynchronously() affects the task you run this on. If the call chain later contains more async calls, they run asynchronously.
I have a little console app that is modeling this, is someone is interested in seeing it, but the concept is pretty simple to reproduce - just chain enough asynchronous calls and toggle between running the earliest one synchronously and asynchronously to see the different behavior.
I'm trying to provide a functionality of having two Methods one called StartTask(action mymethod)
and the other called StopTask();
problem is the action has to have access to the CancellationTokenSource to check for cancellation and exit the method (return) which is not really what i want the method could be in another component or layer , i cant push every Method to have access to that cancellationtokensource,
i cant push the designer/developer of the component which have the process method to check for cancellation and return.
is there is any way to have something like this , i know it sound strange and inapplicable , just thought of asking.
this is the best i got:
CancellationTokenSource cancellationTokenSource;
private void button1_Click(object sender, EventArgs e)
{
cancellationTokenSource = new CancellationTokenSource();
Task t = new Task(() => Dowork(CancellationAction), cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
t.Start();
}
private bool CancellationAction()
{
if (cancellationTokenSource.IsCancellationRequested)
{
label1.Invoke(new MethodInvoker(() =>
{
label1.Text = "Cancellation Requested!";
}));
return true;
}
return false;
}
private void Dowork(Func<bool> Return)
{
int x = 1;
while (true)
{
x++;
label1.Invoke(new MethodInvoker(() =>
{
label1.Text = x.ToString();
}));
Thread.Sleep(1000);
if (Return())
{
return;
}
}
}
problem with this is DoWork now has to have one parameter which is func , but what if the method already takes other parameters ? the creation of task will be in another class which might not have any idea what parameters to pass beside CancellationAction
If the component does not provide a way to cancel one of its running tasks, then the caller should not be able to cancel it. It could leave the application/database/anything in an unknown state.
So basically the lower level component should provide the caller with a way to cancel a task (ManualResetEvent, CancelAsync method like the BackgroundWorker, etc.). Otherwise the caller should wait for it to finish.
If the lower level component does not provide such a feature, it is most of the time considered as bad design.
I'm not sure that I entirely understand your question, but I'll take a stab at it. It seems like you're trying to solve two problems at once here.
First you're trying to pass parameters to an asynchronous thread and/or cancel that thread (very similar issues). As others have stated BackgroundWorker already handles canceling. That implementation is similar to passing any argument to your thread. If I were replicating that functionality for instance I'd add a Cancel property or method to my worker thread that any other component could call and check a backing value in my main thread loop. No reason to do that for canceling threads these days, just an example of passing and using values to a worker thread.
The other problem that it looks like you need to solve is how to send messages between different parts of your application that shouldn't otherwise need to reference each other. Typically I've seen this done with a service provider of some sort. Implement an interface on a context or common model that all components receive an instance of or have easy access to. The interface should contain any events, methods and properties so the different components can communicate.
E.g. (probably a bad example but...) If my grammar checking routine should cancel when a document is closed, I would define a DocumentClosing event and OnDocumentClosing method on an IDocumentService interface and implement that interface in an appropriate context/model. When creating my document viewer UI component and grammar checker thread component I would inject an instance of the context/model typed as the interface. When the document viewer starts to close the document, it calls the OnDocumentClosing method from the interface. When the thread is created it would attach to the DocumentClosing event and if the event fires a flag is set. Then at intervals while checking grammar, I would check the flag and cancel as appropriate.
This sort of implementation gives you the flexibility to have any component trigger appropriate events and any other component react to them regardless of where in your application the components are used. In fact, this approach is useful even in synchronous situations such as menu items changing state in response to application events. It allows for easy unit testing of all your components. And the segregation of responsibility means that you can easily change any of the trigger points and responses as needed.
Why don't you use BackgroundWorkerThread or other threading mechanism?
Is there a particular reason for using Task Parallel Library?
BackgroundWorkerThread will give you a change to cancel the task and then respond to cancellation.