SqlConnection.OpenAsync doesn't work on .net 4.5^ - ado.net

I have a method with a signature like this:
internal async static Task<string> Get()
{
var SqlCon = await InitializeConnection();
return "Foo";
}
I call this method like this:
var x = Get().Result;
Description of other method
internal async static Task<SqlConnection> InitializeConnection()
{
SqlConnection sc;
sc = new SqlConnection();
sc.ConnectionString = #"Data Source=.\MSSQL;Initial Catalog=MyDB;Integrated Security=True;Async=True";
await sc.OpenAsync();//on this line the program long waits and doesn't connect
return sc;
}
I checked with different correct lines of connection without use of asynchrony and everything worked. How to fix it ? Thank you.

You are probably causing a deadlock by using Result. You should use await instead.
I explain this deadlock in detail on my blog. In essence, there are many contexts (such as UI or ASP.NET contexts) that only permit a single thread to execute at a time. By default, await will capture a context and resume the rest of the async method in that context. So, by (synchronously) blocking a thread in that context by calling Result, you are preventing the async method from completing.

Related

Vertx: Using AbstractVerticle Context to pass around objects

We have been using the Context object to in a long chain of async execution.
e.g.:
private void checkVehicle(final JsonObject cmd,
final RedisFleetStorage storage,
final Handler<AsyncResult<String>> handler) {
// omitted for brevity
// some async call to another verticle
storage.getVehicle(fleetId, vehicleId, result -> {
if (!result.succeeded()) {
LOG.error(String.format("Impossible to get vehicleStatus %s:%s", fleetId, vehicleId), result.cause());
handler.handle(Future.failedFuture("KO");
return;
}
// put vehicle in context for later use
final Vehicle vehicle = result.result();
LOG.info("vehicle details {}", vehicle);
context.put("vehicle", vehicle);
handler.handle(Future.succeededFuture());
});
}
As seen above, we put an object (vehicle) in the context and then access later in the execution.
But we suspect that the vehicle object it's altered by another execution. Is it possible? Can another event-loop change the object in the context?
A verticle instance handles all requests with the same event loop.
This why the Context object is not suited for storage of request specific data.

Create async methods to load data from database using EF

how does one write an async method that gets data from database, using DbContext and .NET 4.0?
public Task<List<Product>> GetProductsAsync()
{
// Context.Set<Product>().ToList();
}
so we can await somewhere for result of this method
// somewhere
List<Product> products = await repository.GetProductsAsync();
What is important is that I do not want to use thread pool thread for this task, since this is an IO task, and I need to support framework 4.0, and EF6 had added support for async methods only in 4.5, if I am not mistaken.
Not possible, SaveAsync is wrapped with:
#if !NET40
Source: https://github.com/aspnet/EntityFramework6/blob/master/src/EntityFramework/DbContext.cs#L335
Installing Entity Framework 6 is available as a Nuget Package and works also with .NET 4. In EF6, async
DB calls can be done like this example:
public static async Task<List<Customer>> SelectAllAsync()
{
using (var context = new NorthWindEntities())
{
var query = from c in context.Customers
orderby c.CustomerID ascending
select c;
return await query.ToListAsync();
}
}
Here, a DbContext is instantiated in a using block and the query will search the Northwind database for all its customers and order ascending by primary key CustomerID. The method needs to be decorated with async keyword and must return a task of the desired type T, here a list of customers. The result will then be return by using the ToListAsync() method in this case and one must remember to use the await keyword. There are additional Async methods in EF6, such as SaveChangesAsync, SingleOrDefaultAsync and so on. Also, async methods in C# should following this naming conventions according to guidelines.
To get started test the code above in Visual Studio, just create a new Console Application solution, type: install-package EntityFramework in the Package Manager Console and add an edmx file pointing to a local Northwind database. The main method will then just call the method above like this:
class Program
{
static void Main(string[] args)
{
Stopwatch sw = Stopwatch.StartNew();
var task = CustomHelper.SelectAllAsync();
task.Wait();
Console.WriteLine("Got data!");
List<Customer> data = task.Result;
Console.WriteLine(data.Count);
Console.WriteLine("Async op took: " + sw.ElapsedMilliseconds);
sw.Stop();
sw.Start();
//data =
//var data = CustomHelper.SelectAll();
//Console.WriteLine("Got data!");
//Console.WriteLine(data.Count);
//Console.WriteLine("Sync operation took: " + sw.ElapsedMilliseconds);
Console.WriteLine("Press any key to continue ...");
Console.ReadKey();
}
}
I see that the async operation takes a bit longer than the sync operation, so the async db call will have some time penalty but allows asynchronous processing, not freezing the calling code awaiting the result in a blocking fashion.

How to access memcached asynchronously in netty

I am writing a server in netty, in which I need to make a call to memcached. I am using spymemcached and can easily do the synchronous memcached call. I would like this memcached call to be async. Is that possible? The examples provided with netty do not seem to be helpful.
I tried using callbacks: created a ExecutorService pool in my Handler and submitted a callback worker to this pool. Like this:
public class MyHandler extends ChannelInboundMessageHandlerAdapter<MyPOJO> implements CallbackInterface{
...
private static ExecutorService pool = Executors.newFixedThreadPool(20);
#Override
public void messageReceived(ChannelHandlerContext ctx, MyPOJO pojo) {
...
CallingbackWorker worker = new CallingbackWorker(key, this);
pool.submit(worker);
...
}
public void myCallback() {
//get response
this.ctx.nextOutboundMessageBuf().add(response);
}
}
CallingbackWorker looks like:
public class CallingbackWorker implements Callable {
public CallingbackWorker(String key, CallbackInterface c) {
this.c = c;
this.key = key;
}
public Object call() {
//get value from key
c.myCallback(value);
}
However, when I do this, this.ctx.nextOutboundMessageBuf() in myCallback gets stuck.
So, overall, my question is: how to do async memcached calls in Netty?
There are two problems here: a small-ish issue with the way you're trying to code this, and a bigger one with many libraries that provide async service calls, but no good way to take full advantage of them in an async framework like Netty. That forces users into suboptimal hacks like this one, or a less-bad, but still not ideal approach I'll get to in a moment.
First the coding problem. The issue is that you're trying to call a ChannelHandlerContext method from a thread other than the one associated with your handler, which is not allowed. That's pretty easy to fix, as shown below. You could code it a few other ways, but this is probably the most straightforward:
private static ExecutorService pool = Executors.newFixedThreadPool(20);
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
//...
final GetFuture<String> future = memcachedClient().getAsync("foo", stringTranscoder());
// first wait for the response on a pool thread
pool.execute(new Runnable() {
public void run() {
String value;
Exception err;
try {
value = future.get(3, TimeUnit.SECONDS); // or whatever timeout you want
err = null;
} catch (Exception e) {
err = e;
value = null;
}
// put results into final variables; compiler won't let us do it directly above
final fValue = value;
final fErr = err;
// now process the result on the ChannelHandler's thread
ctx.executor().execute(new Runnable() {
public void run() {
handleResult(fValue, fErr);
}
});
}
});
// note that we drop through to here right after calling pool.execute() and
// return, freeing up the handler thread while we wait on the pool thread.
}
private void handleResult(String value, Exception err) {
// handle it
}
That will work, and might be sufficient for your application. But you've got a fixed-sized thread pool, so if you're ever going to handle much more than 20 concurrent connections, that will become a bottleneck. You could increase the pool size, or use an unbounded one, but at that point, you might as well be running under Tomcat, as memory consumption and context-switching overhead start to become issues, and you lose the scalabilty that was the attraction of Netty in the first place!
And the thing is, Spymemcached is NIO-based, event-driven, and uses just one thread for all its work, yet provides no way to fully take advantage of its event-driven nature. I expect they'll fix that before too long, just as Netty 4 and Cassandra have recently by providing callback (listener) methods on Future objects.
Meanwhile, being in the same boat as you, I researched the alternatives, and not being too happy with what I found, I wrote (yesterday) a Future tracker class that can poll up to thousands of Futures at a configurable rate, and call you back on the thread (Executor) of your choice when they complete. It uses just one thread to do this. I've put it up on GitHub if you'd like to try it out, but be warned that it's still wet, as they say. I've tested it a lot in the past day, and even with 10000 concurrent mock Future objects, polling once a millisecond, its CPU utilization is negligible, though it starts to go up beyond 10000. Using it, the example above looks like this:
// in some globally-accessible class:
public static final ForeignFutureTracker FFT = new ForeignFutureTracker(1, TimeUnit.MILLISECONDS);
// in a handler class:
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
// ...
final GetFuture<String> future = memcachedClient().getAsync("foo", stringTranscoder());
// add a listener for the Future, with a timeout in 2 seconds, and pass
// the Executor for the current context so the callback will run
// on the same thread.
Global.FFT.addListener(future, 2, TimeUnit.SECONDS, ctx.executor(),
new ForeignFutureListener<String,GetFuture<String>>() {
public void operationSuccess(String value) {
// do something ...
ctx.fireChannelRead(someval);
}
public void operationTimeout(GetFuture<String> f) {
// do something ...
}
public void operationFailure(Exception e) {
// do something ...
}
});
}
You don't want more than one or two FFT instances active at any time, or they could become a drain on CPU. But a single instance can handle thousands of outstanding Futures; about the only reason to have a second one would be to handle higher-latency calls, like S3, at a slower polling rate, say 10-20 milliseconds.
One drawback of the polling approach is that it adds a small amount of latency. For example, polling once a millisecond, on average it will add 500 microseconds to the response time. That won't be an issue for most applications, and I think is more than offset by the memory and CPU savings over the thread pool approach.
I expect within a year or so this will be a non-issue, as more async clients provide callback mechanisms, letting you fully leverage NIO and the event-driven model.

EF6 alpha Async Await on an Entity Stored Procedure / Function Import?

I'd like to apply the new async await functionality to Stored Procedures / Function Imports imported in my Entity model, but have as yet been unable to with the EF6 alpha.
Is it yet possible in EF6 alpha2 (or the nightly build as of 20211) to call any of the new Async methods on an Entity Function Import (which calls a SQL Stored Procedure) that returns a collection of Complex Type? e.g.
private async Task<IList<Company>> getInfo (string id)
{
using (CustomEntity context = new CustomEntity())
{
var query = await context.customStoredProcedure(id).ToListAsync();
// ".ToListAsync()" method not available on above line
// OR ALTERNATIVELY
var query = await (from c in context.customStoredProcedure(id)
select new Company
{
Ident = c.id,
Name = c.name,
Country = c.country,
Sector = c.sector,
etc. etc....
}).ToListAsync();
// ".ToListAsync()" method or any "...Async" methods also not available this way
return query;
}
}
"ToListAsync", or any of the new async modified methods do not seem to be available to the above Entity Stored Procedure / Function Import; only the standard "ToList" or "AsNumerable" etc methods are available.
I followed this (http://entityframework.codeplex.com/wikipage?title=Updating%20Applications%20to%20use%20EF6) to make sure the code is referencing the new EF6 dlls and not EF5, as well as updated the various using statements. Aside from above, everything builds correctly. (.NET Framework 4.5)
The only time I can see the async methods is if instead of only importing stored procedures from the DB, I also import a table--then when referencing that table via the Entity context as above (context.SomeTable), some of the async methods appear in intellisense.
I'd really like to start using the new async await functionality on multiple Stored Procedures prior to returning data as JSON, but have not been able to get it to work so far.
Am I doing something wrong? Is async functionality not possible on Entity stored procedure / function imports? Thanks for your advice.
Now this is by no means the best solution. I added an extension method so that I could call await on my stored procedures. In the newer releases of EF6.1+ we should see this officially implemented. Until then a dummy extension method does the job.
static async Task<List<T>> ToListAsync<T>(this ObjectResult<T> source)
{
var list = new List<T>();
await Task.Run(() => list.AddRange(source.ToList()));
return list;
}
If you reflect version 6 of EF you will see that ObjectResult<T> actually implements IDbAsyncEnumerable<T>, IDbAsyncEnumerable. And the method for ToListAsync<T>(this IDbAsyncEnumerable<T> source) should be able to wire it up the same as a LINQ query.
Edit
When the ObjectResult is empty null is returned. You could add if (source == null) return new List<T>(); if you want to return an empty List instead of null.
This is an old thread, but I felt I should share. You should use APM then wrap the synchronous calls in a Task.
Example:
//declare the delegate
private delegate MyResult MySPDelegate();
// declare the synchronous method
private MyResult MySP()
{
// do work...
}
Then wrap the synchronous method in a Task:
// wraps the method in a task and returns the task.
public Task<MyResult> MySPAsync()
{
MySPDelegate caller = new MySPDelegate(MySP);
return Task.Factory.FromAsync(caller.BeginInvoke, caller.EndInvoke, null);
}
Call the async method when you want to execute:
var MyResult = await MySPAsync();
You can use up to three (3) parameters in the methods. Best practice is if you use more than three parameters; you should pass in a class.

WCF RIA Exception on Invoke operation interrupts Caliburn.Micro coroutine execution?

I am executing a series of Caliburn.Micro IResults by yield returning them from an IEnumerable method called by a Caliburn.Micro action message. The first IResult calls a WCF RIA service Invoke operation. Sometimes this operation fails and throws an exception. This is handled in the IResult where the InvokeOperation object is checked for error, I mark the error as handled and set the IResult's error message field to the error so I can recover it from the client.
The problem is that for some reason this interrupts the co-routine executing. I can't think of any good reason why, but when I'm in debug mode VS skips to the server code and bring up the unhandled exception helper telling me there was an uncaught exception (duh), and the co-routine never continues executing the other members of the IEnumerable.
Here is some of the code.
Called from the Action Message:
public IEnumerable<IResult> Submit()
{
var register = new RegisterUserResult(Username, Password, Email, _userModel);
yield return register;
if (register.Success)
{
if (RegisterAsTrainer)
yield return new ApplyRoleToUserResult(Username, "Trainer", _userModel);
yield return new NavigateResult(new Uri("/MainPageViewModel", UriKind.Relative));
}
else ErrorMessage = register.ErrorMessage;
}
The code in the DomainService (which sometimes throws an exception)
[Invoke]
public void CreateUser(string username, string password, string email)
{
Membership.CreateUser(username, password, email);
}
...where Membership is the ASP.NET class, which I am using for membership management.
The IResult that calls the above service (some details elided for clarity):
public void Execute(ActionExecutionContext context)
{
ErrorMessage = null;
Success = false;
var ctx = new TrainingContext();
ctx.CreateUser(_username, _password, _email, CreateUserCallback, null);
}
private void CreateUserCallback(InvokeOperation invokeOp)
{
if (invokeOp.HasError)
invokeOp.MarkErrorAsHandled();
Completed(this, new ResultCompletionEventArgs
{
Error = invokeOp.Error,WasCancelled = invokeOp.IsCanceled
});
}
The IResult.Completed DOES fire, but the rest of the method never executes. I'm literally tearing my hair out with this, please please help me.
Ugh I figured this out, stupid me. I was setting the IResult Error field, thinking I'd need to use that information later. I didn't know that having a non-null Error field would cause co-routine execution to halt (I thought only the Canceled field would do that). I'll leave this here in case anyone else runs into this issue.