MySQL C# async methods doesn't work? -
i have database in server , seems async method doesn't work.
here code:
static async void example() { string connectionstring = "server=mydomainname.com;" + "port=3306;" + "database=scratch;" + "uid=assassinbeast;" + "password=mypass123;" + "allowuservariables= true;"; mysql.data.mysqlclient.mysqlconnection sqconnection = new mysql.data.mysqlclient.mysqlconnection(connectionstring); await sqconnection.openasync(); console.write("opened. click close"); console.readline(); sqconnection.close(); } static void main(string[] args) { console.readline(); example(); console.writeline("done"); console.readline(); } at "await" statement, supposed jump main() function , writeout "done". not doing that. running synchronously wasn't async method , first write "done" once function completed.
so doing wrong? bug?
update
okay, after got answers, still couldn't see difference between openasync() , open().
i began trying test more things out , think can conclude async method does not work
here new code:
static async task example() { string connectionstring = "server=mydomainname.com;" + "port=3306;" + "database=scratch;" + "uid=assassinbeast;" + "password=mypass123;" + "allowuservariables= true;"; using (var sqconnection = new mysql.data.mysqlclient.mysqlconnection(connectionstring)) { console.writeline("opening"); await sqconnection.openasync(); console.writeline("opened. closing"); } } static async task example2() { //lets pretend database computer try connect console.writeline("opening"); await task.delay(1000); //lets takes 1 second open console.writeline("opened. closing"); } static void main(string[] args) { console.readline(); task.run(() => example()); task.run(() => example()); task.run(() => example()); task.run(() => example()); task.run(() => example()); task.run(() => console.writeline("done")); console.readline(); } here when run example() 5 times, output this:

it takes 3 seconds before write out "done". note computer not working on cpu @ all, because waiting , connecting database takes around 1 second connect to.
so blocking computers thread , not running multithreaded, otherwise write out "done" immediedtly.
so if called example2() instead of example(), result want , expect:

here, true async method, because can on 6 things @ time on computer has 2 cores. first example, 2 things @ time because mysql async method not work.
i tested sqconnection.open(), had exact same result sqconnection.openasync()
so right now, cant figure out how connect database 5 times @ same time.
judging old code (6.7.2), appears mysql ado.net provider not implement of async functionality correctly. includes tap pattern , older style begin..., end... async patterns. in version, db* async methods appear not written @ all; using base class ones in .net synchronous , like:
public virtual task<int> executenonqueryasync(...) { return task.fromresult(executenonquery(...)); } (100% synchronous added overhead of wrapping in task; reference source here)
if begin , end versions written correctly (they aren't) implemented this:
public override task<int> executenonqueryasync(...) { return task<int>.factory.fromasync(beginexecutenonqueryasync, endexecutenonqueryasync, null); } (reference source method sqlcommand)
doing dependent on sort of callback api underlying socket deal in pattern caller sends bytes on socket , registered method gets called underlying network stack when ready.
however, mysql connector doesn't (it doesn't override method in first place; if did, relevant begin , end methods aren't async on underlying socket api). mysql connector instead build delegate internal method on current connection instance , invokes synchronously on separate thread. cannot in meantime example execute second command on same connection, this:
private static void main() { var sw = new stopwatch(); sw.start(); task.waitall( getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync(), getdelaycommand().executenonqueryasync()); sw.stop(); console.writeline(sw.elapsed.seconds); } private static dbcommand getdelaycommand() { var connection = new mysqlconnection (...); connection.open(); var cmd = connection.createcommand(); cmd.commandtext = "sleep(5)"; cmd.commandtype = commandtype.text; return cmd; } (assuming connection pooling , number of tasks there more maximum pool size; if async worked code number depending on number of connections in pool instead of number depending on both , number of threads can run concurrently)
this because code has lock on driver (the actual thing manages network internals; *). , if didn't (and internals otherwise thread safe , other way used manage connection pools) it goes on perform blocking calls on underlying network stream.
so yeah, no async support in sight codebase. @ newer driver if point me code, suspect internal networkstream based objects not different , async code not looking different either. async supporting driver have of internals written depend on asynchronous way of doing , have synchronous wrapper synchronous code; alternatively lot more sqlclient reference source , depend on task wrapping library abstract away differences between running synchronously or async.
* locking on driver doesn't mean couldn't possibly using non-blocking io, method couldn't have been written lock statement , use non-blocking begin/end iasyncresult code have been written prior tap patterns.
edit: downloaded 6.9.8; suspected there no functioning async code (non-blocking io operations); there bug filed here: https://bugs.mysql.com/bug.php?id=70111
update july 6 2016: interesting project on github may address @ https://github.com/mysql-net/mysqlconnector (could use more contributors have stake in success [i no longer working on mysql]).
Comments
Post a Comment