|
1 | 1 | using System;
|
| 2 | +using System.Collections.Generic; |
2 | 3 | using System.Data;
|
3 | 4 | using System.Linq;
|
| 5 | +using System.Threading; |
4 | 6 | using System.Threading.Tasks;
|
5 | 7 | using Dapper;
|
6 | 8 | using MySql.Data.MySqlClient;
|
@@ -470,12 +472,79 @@ public void SumInts()
|
470 | 472 | }
|
471 | 473 | }
|
472 | 474 |
|
| 475 | + [Fact] |
| 476 | + public void UseReaderWithoutDisposing() |
| 477 | + { |
| 478 | + var csb = AppConfig.CreateConnectionStringBuilder(); |
| 479 | + csb.MaximumPoolSize = 8; |
| 480 | + |
| 481 | + using (var connection = new MySqlConnection(csb.ConnectionString)) |
| 482 | + { |
| 483 | + connection.Execute(@"drop table if exists dispose_reader; |
| 484 | + create table dispose_reader(value int not null); |
| 485 | + insert into dispose_reader(value) values(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);"); |
| 486 | + } |
| 487 | + |
| 488 | + var threads = new List<Thread>(); |
| 489 | + var threadData = new UseReaderWithoutDisposingThreadData(new List<Exception>(), csb); |
| 490 | + for (int i = 0; i < csb.MaximumPoolSize + 4; i++) |
| 491 | + { |
| 492 | + var thread = new Thread(UseReaderWithoutDisposingThread); |
| 493 | + threads.Add(thread); |
| 494 | + thread.Start(threadData); |
| 495 | + } |
| 496 | + foreach (var thread in threads) |
| 497 | + thread.Join(); |
| 498 | + foreach (var ex in threadData.Exceptions) |
| 499 | + throw ex; |
| 500 | + } |
| 501 | + |
| 502 | + private void UseReaderWithoutDisposingThread(object obj) |
| 503 | + { |
| 504 | + var data = (UseReaderWithoutDisposingThreadData) obj; |
| 505 | + |
| 506 | + try |
| 507 | + { |
| 508 | + for (int i = 0; i < 100; i++) |
| 509 | + { |
| 510 | + using (var connection = new MySqlConnection(data.ConnectionStringBuilder.ConnectionString)) |
| 511 | + { |
| 512 | + connection.Open(); |
| 513 | + using (var cmd = connection.CreateCommand()) |
| 514 | + { |
| 515 | + cmd.CommandText = @"select * from dispose_reader;"; |
| 516 | + var reader = cmd.ExecuteReader(); |
| 517 | + reader.Read(); |
| 518 | + } |
| 519 | + } |
| 520 | + } |
| 521 | + } |
| 522 | + catch (Exception ex) |
| 523 | + { |
| 524 | + lock (data) |
| 525 | + data.Exceptions.Add(ex); |
| 526 | + } |
| 527 | + } |
| 528 | + |
473 | 529 | class BoolTest
|
474 | 530 | {
|
475 | 531 | public int Id { get; set; }
|
476 | 532 | public bool? IsBold { get; set; }
|
477 | 533 | }
|
478 | 534 |
|
| 535 | + class UseReaderWithoutDisposingThreadData |
| 536 | + { |
| 537 | + public UseReaderWithoutDisposingThreadData(List<Exception> exceptions, MySqlConnectionStringBuilder csb) |
| 538 | + { |
| 539 | + Exceptions = exceptions; |
| 540 | + ConnectionStringBuilder = csb; |
| 541 | + } |
| 542 | + |
| 543 | + public List<Exception> Exceptions { get; } |
| 544 | + |
| 545 | + public MySqlConnectionStringBuilder ConnectionStringBuilder { get; } |
| 546 | + } |
| 547 | + |
479 | 548 | readonly DatabaseFixture m_database;
|
480 | 549 | }
|
481 | 550 | }
|
0 commit comments