@@ -11,4 +11,159 @@ weight: 10
11
11
Best Practices
12
12
=============
13
13
14
- Best Practices
14
+ ## Asynchronous Operation
15
+
16
+ MySqlConnector is fully asynchronous, supporting the async ADO.NET methods added in .NET 4.5 without blocking
17
+ or using ` Task.Run ` to run synchronous methods on a background thread. Programmers implementing MySqlConnector
18
+ should be familiar with [ Async/Await - Best Practices in Asynchronous Programming] ( https://msdn.microsoft.com/en-us/magazine/jj991977.aspx ) .
19
+
20
+ ### Always Use Async when possible
21
+
22
+ <table class =" table table-bordered table-head-centered " style =" max-width : 650px " >
23
+ <thead >
24
+ <th style="width:30%">ADO.NET Class</th>
25
+ <th class="success" style="width:40%">Asynchronous Method<br />(always use when possible)</th>
26
+ <th class="warning" style="width:30%">Synchronous Method<br />(avoid when possible)</th>
27
+ </thead >
28
+ <tr >
29
+ <td rowspan="2" style="vertical-align:middle">
30
+ <a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbconnection">DbConnection</a>
31
+ </td>
32
+ <td>OpenAsync</td>
33
+ <td>Open</td>
34
+ </tr >
35
+ <tr >
36
+ <td>
37
+ <span class="text-danger">*</span><a href="api/mysql-db-connection">MySqlDbConnection</a>.BeginTransactionAsync
38
+ </td>
39
+ <td>BeginTransaction</td>
40
+ </tr >
41
+ <tr >
42
+ <td rowspan="3" style="vertical-align:middle">
43
+ <a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbcommand">DbCommand</a>
44
+ </td>
45
+ <td>ExecuteNonQueryAsync</td>
46
+ <td>ExecuteNonQuery</td>
47
+ </tr >
48
+ <tr >
49
+ <td>ExecuteReaderAsync</td>
50
+ <td>ExecuteReader</td>
51
+ </tr >
52
+ <tr >
53
+ <td>ExecuteScalarAsync</td>
54
+ <td>ExecuteScalar</td>
55
+ </tr >
56
+ <tr >
57
+ <td rowspan="4" style="vertical-align:middle">
58
+ <a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbdatareader">DbDataReader</a>
59
+ </td>
60
+ <td>GetFieldValueAsync</td>
61
+ <td>GetFieldValue</td>
62
+ </tr >
63
+ <tr >
64
+ <td>IsDBNullAsync</td>
65
+ <td>IsDBNull</td>
66
+ </tr >
67
+ <tr >
68
+ <td>NextResultAsync</td>
69
+ <td>NextResult</td>
70
+ </tr >
71
+ <tr >
72
+ <td>ReadAsync</td>
73
+ <td>Read</td>
74
+ </tr >
75
+ <tr >
76
+ <td rowspan="2" style="vertical-align:middle">
77
+ <a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbtransaction">DbTransaction</a>
78
+ </td>
79
+ <td>
80
+ <span class="text-danger">*</span><a href="api/mysql-db-transaction">MySqlDbTransaction</a>.CommitAsync
81
+ </td>
82
+ <td>Commit</td>
83
+ </tr >
84
+ <tr >
85
+ <td>
86
+ <span class="text-danger">*</span><a href="api/mysql-db-transaction">MySqlDbTransaction</a>.RollbackAsync
87
+ </td>
88
+ <td>Rollback</td>
89
+ </tr >
90
+ </table >
91
+
92
+ <span class =" text-danger " >* </span >Async Transaction methods are not part of ADO.NET, they are provided by
93
+ MySqlConnector to allow database code to remain fully asynchronous.
94
+
95
+ ### Example Console Application
96
+
97
+ In order to get the full benefit of asynchronous operation, every method in the call stack that eventually calls
98
+ MySqlConnector should be implemented as an async method. The exception is the ` static void Main ` method in a Console Application.
99
+
100
+ Example assumes a [ configured AppDb] ( overview/configuration ) object in the ` MySqlConnector.Examples ` namespace.
101
+
102
+ ``` csharp
103
+ using System .Threading .Tasks ;
104
+ using System .Collections .Generic ;
105
+
106
+ namespace MySqlConnector .Examples
107
+ {
108
+ public class Program
109
+ {
110
+ public static void Main (string [] args )
111
+ {
112
+ MainAsync (args ).GetAwaiter ().GetResult ();
113
+ }
114
+
115
+ public static async Task MainAsync (string [] args )
116
+ {
117
+ var tasks = new List <Task >();
118
+ for (var i = 0 ; i < 100 ; i ++ ){
119
+ tasks .Add (Controllers .SleepOne ());
120
+ }
121
+ // these 100 queries should all complete in around
122
+ // 1 second if "Max Pool Size=100" (the default)
123
+ await Task .WhenAll (tasks );
124
+ }
125
+ }
126
+
127
+ public class Controllers
128
+ {
129
+ public static async Task SleepOne ()
130
+ {
131
+ using (var db = new AppDb ())
132
+ {
133
+ await db .OpenAsync ();
134
+ var cmd = db .Connection .CreateCommand ();
135
+ cmd .CommandText = @" SELECT SLEEP(1)" ;
136
+ await cmd .ExecuteNonQueryAsync ();
137
+ }
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+
144
+ ## Synchronous Operation
145
+
146
+ <div class =" alert alert-warning " >
147
+ Using Synchronous Methods can have adverse effects on the managed thread pool and cause slowdowns or lock-ups
148
+ if not properly tuned. The recommended approach is to use all Asynchronous Methods.
149
+ </div >
150
+
151
+ If you must use synchronous methods, ensure that your thread pool is at least the size of the number of
152
+ concurrent connections you plan to support. For example, if you are creating a web server using
153
+ synchronous methods that needs to support serving 500 Requests Per Second, set the minimum thread
154
+ pool size to 500.
155
+
156
+ Example ` project.json ` configuration:
157
+
158
+ ``` json
159
+ {
160
+ "runtimeOptions" : {
161
+ "configProperties" : {
162
+ "System.GC.Server" : true ,
163
+ "System.GC.Concurrent" : true ,
164
+ "System.Threading.ThreadPool.MinThreads" : 500
165
+ }
166
+ },
167
+ // other config
168
+ }
169
+ ```
0 commit comments