Skip to content

Best Practices Documentation #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ date: 2016-10-16
menu:
main:
parent: api
title: DbCommand
title: MySqlDbCommand
weight: 20
---

DB Command
==========
MySqlDbCommand
==============

DB Command
MySqlDbCommand
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ date: 2016-10-16
menu:
main:
parent: api
title: DbConnection
title: MySqlDbConnection
weight: 10
---

DB Connection
==========
MySqlDbConnection
=================

DB Connection
MySqlDbConnection
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ date: 2016-10-16
menu:
main:
parent: api
title: Result Set
title: MySqlDbDataReader
weight: 30
---

Result Set
==========
MySqlDbDataReader
=================

Result Set
MySqlDbDataReader
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ date: 2016-10-16
menu:
main:
parent: api
title: Transaction
title: MySqlDbTransaction
weight: 40
---

Transaction
MySqlDbTransaction
==========

Transaction
MySqlDbTransaction
157 changes: 156 additions & 1 deletion docs/content/tutorials/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,159 @@ weight: 10
Best Practices
=============

Best Practices
## Asynchronous Operation

MySqlConnector is fully asynchronous, supporting the async ADO.NET methods added in .NET 4.5 without blocking
or using `Task.Run` to run synchronous methods on a background thread. Programmers implementing MySqlConnector
should be familiar with [Async/Await - Best Practices in Asynchronous Programming](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx).

### Always Use Async when possible

<table class="table table-bordered table-head-centered" style="max-width: 650px">
<thead>
<th style="width:30%">ADO.NET Class</th>
<th class="success" style="width:40%">Asynchronous Method<br />(always use when possible)</th>
<th class="warning" style="width:30%">Synchronous Method<br />(avoid when possible)</th>
</thead>
<tr>
<td rowspan="2" style="vertical-align:middle">
<a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbconnection">DbConnection</a>
</td>
<td>OpenAsync</td>
<td>Open</td>
</tr>
<tr>
<td>
<span class="text-danger">*</span><a href="api/mysql-db-connection">MySqlDbConnection</a>.BeginTransactionAsync
</td>
<td>BeginTransaction</td>
</tr>
<tr>
<td rowspan="3" style="vertical-align:middle">
<a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbcommand">DbCommand</a>
</td>
<td>ExecuteNonQueryAsync</td>
<td>ExecuteNonQuery</td>
</tr>
<tr>
<td>ExecuteReaderAsync</td>
<td>ExecuteReader</td>
</tr>
<tr>
<td>ExecuteScalarAsync</td>
<td>ExecuteScalar</td>
</tr>
<tr>
<td rowspan="4" style="vertical-align:middle">
<a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbdatareader">DbDataReader</a>
</td>
<td>GetFieldValueAsync</td>
<td>GetFieldValue</td>
</tr>
<tr>
<td>IsDBNullAsync</td>
<td>IsDBNull</td>
</tr>
<tr>
<td>NextResultAsync</td>
<td>NextResult</td>
</tr>
<tr>
<td>ReadAsync</td>
<td>Read</td>
</tr>
<tr>
<td rowspan="2" style="vertical-align:middle">
<a href="https://docs.microsoft.com/en-us/dotnet/core/api/system.data.common.dbtransaction">DbTransaction</a>
</td>
<td>
<span class="text-danger">*</span><a href="api/mysql-db-transaction">MySqlDbTransaction</a>.CommitAsync
</td>
<td>Commit</td>
</tr>
<tr>
<td>
<span class="text-danger">*</span><a href="api/mysql-db-transaction">MySqlDbTransaction</a>.RollbackAsync
</td>
<td>Rollback</td>
</tr>
</table>

<span class="text-danger">*</span>Async Transaction methods are not part of ADO.NET, they are provided by
MySqlConnector to allow database code to remain fully asynchronous.

### Example Console Application

In order to get the full benefit of asynchronous operation, every method in the call stack that eventually calls
MySqlConnector should be implemented as an async method. The exception is the `static void Main` method in a Console Application.

Example assumes a [configured AppDb](overview/configuration) object in the `MySqlConnector.Examples` namespace.

```csharp
using System.Threading.Tasks;
using System.Collections.Generic;

namespace MySqlConnector.Examples
{
public class Program
{
public static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
}

public static async Task MainAsync(string[] args)
{
var tasks = new List<Task>();
for (var i=0; i<100; i++){
tasks.Add(Controllers.SleepOne());
}
// these 100 queries should all complete in around
// 1 second if "Max Pool Size=100" (the default)
await Task.WhenAll(tasks);
}
}

public class Controllers
{
public static async Task SleepOne()
{
using (var db = new AppDb())
{
await db.OpenAsync();
var cmd = db.Connection.CreateCommand();
cmd.CommandText = @"SELECT SLEEP(1)";
await cmd.ExecuteNonQueryAsync();
}
}
}
}
```


## Synchronous Operation

<div class="alert alert-warning">
Using Synchronous Methods can have adverse effects on the managed thread pool and cause slowdowns or lock-ups
if not properly tuned. The recommended approach is to use all Asynchronous Methods.
</div>

If you must use synchronous methods, ensure that your thread pool is at least the size of the number of
concurrent connections you plan to support. For example, if you are creating a web server using
synchronous methods that needs to support serving 500 Requests Per Second, set the minimum thread
pool size to 500.

Example `project.json` configuration:

```json
{
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true,
"System.GC.Concurrent": true,
"System.Threading.ThreadPool.MinThreads": 500
}
},
// other config
}
```
10 changes: 4 additions & 6 deletions docs/layouts/partials/footer.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
{{ $cur := . }}
</div>
<!-- col -->
</div>
<!-- row -->
<div class="row" id="prevNext">
<div class="col-md-9 col-md-offset-3">
<div id="prevNext">
{{ range $i, $el := .Site.Menus.main }}
{{ $.Scratch.Set "tempPrev" "" }}
{{ $.Scratch.Set "parent" "" }}
Expand Down Expand Up @@ -32,6 +27,9 @@
{{ end }}
<div class="clearfix"></div>
</div>
<!-- col -->
</div>
<!-- row -->
</div>
<!-- container -->

Expand Down
10 changes: 10 additions & 0 deletions docs/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,19 @@ h1 {
}

h2 {
margin-top: 30px;
margin-bottom: 20px;
}

h3 {
margin-top: 20px;
margin-bottom: 20px;
}

.table-head-centered th {
text-align: center;
}

.footer {
position: absolute;
bottom: 0;
Expand Down