PageRenderTime 60ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/Src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs

https://github.com/EkardNT/Roslyn
C# | 7065 lines | 6589 code | 370 blank | 106 comment | 117 complexity | 65b60a20701d305e57ea57ce19e17487 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using Microsoft.CodeAnalysis.CSharp.Symbols;
  6. using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
  7. using Microsoft.CodeAnalysis.Test.Utilities;
  8. using Roslyn.Test.Utilities;
  9. using Roslyn.Utilities;
  10. using Xunit;
  11. namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
  12. {
  13. public class CodeGenAsyncTests : EmitMetadataTestBase
  14. {
  15. private CSharpCompilation CreateCompilation(string source, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions compOptions = null)
  16. {
  17. SynchronizationContext.SetSynchronizationContext(null);
  18. compOptions = compOptions ?? TestOptions.OptimizedExe;
  19. IEnumerable<MetadataReference> asyncRefs = new[] { SystemRef_v4_0_30319_17929, SystemCoreRef_v4_0_30319_17929, CSharpRef };
  20. references = (references != null) ? references.Concat(asyncRefs) : asyncRefs;
  21. return CreateCompilationWithMscorlib45(source, compOptions: compOptions, references: references);
  22. }
  23. private CompilationVerifier CompileAndVerify(string source, string expectedOutput, IEnumerable<MetadataReference> references = null, EmitOptions emitOptions = EmitOptions.All, CSharpCompilationOptions compOptions = null, bool emitPdb = false)
  24. {
  25. SynchronizationContext.SetSynchronizationContext(null);
  26. var compilation = this.CreateCompilation(source, references: references, compOptions: compOptions);
  27. return base.CompileAndVerify(compilation, expectedOutput: expectedOutput, emitOptions: emitOptions, emitPdb: emitPdb);
  28. }
  29. [Fact]
  30. public void StructVsClass()
  31. {
  32. var source = @"
  33. using System.Threading;
  34. using System.Threading.Tasks;
  35. class Test
  36. {
  37. public static async Task F(int a)
  38. {
  39. await Task.Factory.StartNew(() => { System.Console.WriteLine(a); });
  40. }
  41. public static void Main()
  42. {
  43. F(123).Wait();
  44. }
  45. }";
  46. var c = CreateCompilationWithMscorlib45(source);
  47. CompilationOptions options;
  48. options = TestOptions.OptimizedExe;
  49. Assert.False(options.EnableEditAndContinue);
  50. CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  51. {
  52. var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  53. Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  54. }, expectedOutput: "123");
  55. options = TestOptions.UnoptimizedExe;
  56. Assert.False(options.EnableEditAndContinue);
  57. CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  58. {
  59. var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  60. Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  61. }, expectedOutput: "123");
  62. options = TestOptions.OptimizedExe.WithDebugInformationKind(DebugInformationKind.Full);
  63. Assert.False(options.EnableEditAndContinue);
  64. CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  65. {
  66. var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  67. Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  68. }, expectedOutput: "123");
  69. options = TestOptions.UnoptimizedExe.WithDebugInformationKind(DebugInformationKind.PdbOnly);
  70. Assert.False(options.EnableEditAndContinue);
  71. CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  72. {
  73. var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  74. Assert.Equal(TypeKind.Struct, stateMachine.TypeKind);
  75. }, expectedOutput: "123");
  76. options = TestOptions.UnoptimizedExe.WithDebugInformationKind(DebugInformationKind.Full);
  77. Assert.True(options.EnableEditAndContinue);
  78. CompileAndVerify(c.WithOptions(options), symbolValidator: module =>
  79. {
  80. var stateMachine = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Test").GetMember<NamedTypeSymbol>("<F>d__1");
  81. Assert.Equal(TypeKind.Class, stateMachine.TypeKind);
  82. }, expectedOutput: "123");
  83. }
  84. [Fact]
  85. public void VoidReturningAsync()
  86. {
  87. var source = @"
  88. using System;
  89. using System.Diagnostics;
  90. using System.Threading;
  91. using System.Threading.Tasks;
  92. class Test
  93. {
  94. static int i = 0;
  95. public static async void F(AutoResetEvent handle)
  96. {
  97. try
  98. {
  99. await Task.Factory.StartNew(() =>
  100. {
  101. Interlocked.Increment(ref Test.i);
  102. });
  103. }
  104. finally
  105. {
  106. handle.Set();
  107. }
  108. }
  109. public static void Main()
  110. {
  111. var handle = new AutoResetEvent(false);
  112. F(handle);
  113. handle.WaitOne(1000 * 60);
  114. Console.WriteLine(i);
  115. }
  116. }";
  117. var expected = @"
  118. 1
  119. ";
  120. CompileAndVerify(source, expectedOutput: expected);
  121. }
  122. [Fact]
  123. [WorkItem(624970, "DevDiv")]
  124. public void AsyncWithEH()
  125. {
  126. var source = @"
  127. using System;
  128. using System.Diagnostics;
  129. using System.Threading;
  130. using System.Threading.Tasks;
  131. class Test
  132. {
  133. static int awaitCount = 0;
  134. static int finallyCount = 0;
  135. static void LogAwait()
  136. {
  137. Interlocked.Increment(ref awaitCount);
  138. }
  139. static void LogException()
  140. {
  141. Interlocked.Increment(ref finallyCount);
  142. }
  143. public static async void F(AutoResetEvent handle)
  144. {
  145. try
  146. {
  147. await Task.Factory.StartNew(LogAwait);
  148. try
  149. {
  150. await Task.Factory.StartNew(LogAwait);
  151. try
  152. {
  153. await Task.Factory.StartNew(LogAwait);
  154. try
  155. {
  156. await Task.Factory.StartNew(LogAwait);
  157. throw new Exception();
  158. }
  159. catch (Exception)
  160. {
  161. }
  162. finally
  163. {
  164. LogException();
  165. }
  166. await Task.Factory.StartNew(LogAwait);
  167. throw new Exception();
  168. }
  169. catch (Exception)
  170. {
  171. }
  172. finally
  173. {
  174. LogException();
  175. }
  176. await Task.Factory.StartNew(LogAwait);
  177. throw new Exception();
  178. }
  179. catch (Exception)
  180. {
  181. }
  182. finally
  183. {
  184. LogException();
  185. }
  186. await Task.Factory.StartNew(LogAwait);
  187. }
  188. finally
  189. {
  190. handle.Set();
  191. }
  192. }
  193. public static void Main2(int i)
  194. {
  195. try
  196. {
  197. awaitCount = 0;
  198. finallyCount = 0;
  199. var handle = new AutoResetEvent(false);
  200. F(handle);
  201. var completed = handle.WaitOne(1000 * 60);
  202. if (completed)
  203. {
  204. if (awaitCount != 7 || finallyCount != 3)
  205. {
  206. throw new Exception(""failed at i="" + i);
  207. }
  208. }
  209. else
  210. {
  211. Console.WriteLine(""Test did not complete in time."");
  212. }
  213. }
  214. catch (Exception ex)
  215. {
  216. Console.WriteLine(""unexpected exception thrown:"");
  217. Console.WriteLine(ex.ToString());
  218. }
  219. }
  220. public static void Main()
  221. {
  222. for (int i = 0; i < 1500; i++)
  223. {
  224. Main2(i);
  225. }
  226. }
  227. }";
  228. var expected = @"";
  229. CompileAndVerify(source, expectedOutput: expected);
  230. }
  231. [Fact, WorkItem(855080, "DevDiv")]
  232. public void GenericCatchVariableInAsyncMethod()
  233. {
  234. var source = @"
  235. using System;
  236. using System.Collections.Generic;
  237. using System.Linq;
  238. using System.Text;
  239. using System.Threading.Tasks;
  240. namespace ConsoleApplication1
  241. {
  242. class Program
  243. {
  244. static void Main(string[] args)
  245. {
  246. Console.WriteLine(Bar().Result);
  247. }
  248. static async Task<int> Bar()
  249. {
  250. NotImplementedException ex = await Foo<NotImplementedException>();
  251. return 3;
  252. }
  253. public static async Task<T> Foo<T>() where T : Exception
  254. {
  255. Task<int> task = null;
  256. if (task != null) await task;
  257. T result = null;
  258. try
  259. {
  260. }
  261. catch (T ex)
  262. {
  263. result = ex;
  264. }
  265. return result;
  266. }
  267. }
  268. }
  269. ";
  270. CompileAndVerify(source, expectedOutput: "3");
  271. }
  272. [Fact]
  273. public void TaskReturningAsync()
  274. {
  275. var source = @"
  276. using System;
  277. using System.Diagnostics;
  278. using System.Threading.Tasks;
  279. class Test
  280. {
  281. static int i = 0;
  282. public static async Task F()
  283. {
  284. await Task.Factory.StartNew(() =>
  285. {
  286. Test.i = 42;
  287. });
  288. }
  289. public static void Main()
  290. {
  291. Task t = F();
  292. t.Wait(1000 * 60);
  293. Console.WriteLine(Test.i);
  294. }
  295. }";
  296. var expected = @"
  297. 42
  298. ";
  299. CompileAndVerify(source, expectedOutput: expected);
  300. }
  301. [Fact]
  302. public void GenericTaskReturningAsync()
  303. {
  304. var source = @"
  305. using System;
  306. using System.Diagnostics;
  307. using System.Threading.Tasks;
  308. class Test
  309. {
  310. public static async Task<string> F()
  311. {
  312. return await Task.Factory.StartNew(() => { return ""O brave new world...""; });
  313. }
  314. public static void Main()
  315. {
  316. Task<string> t = F();
  317. t.Wait(1000 * 60);
  318. Console.WriteLine(t.Result);
  319. }
  320. }";
  321. var expected = @"
  322. O brave new world...
  323. ";
  324. CompileAndVerify(source, expectedOutput: expected);
  325. }
  326. [Fact]
  327. public void AsyncWithLocals()
  328. {
  329. var source = @"
  330. using System;
  331. using System.Threading.Tasks;
  332. class Test
  333. {
  334. public static async Task<int> F(int x)
  335. {
  336. return await Task.Factory.StartNew(() => { return x; });
  337. }
  338. public static async Task<int> G(int x)
  339. {
  340. int c = 0;
  341. await F(x);
  342. c += x;
  343. await F(x);
  344. c += x;
  345. return c;
  346. }
  347. public static void Main()
  348. {
  349. Task<int> t = G(21);
  350. t.Wait(1000 * 60);
  351. Console.WriteLine(t.Result);
  352. }
  353. }";
  354. var expected = @"
  355. 42
  356. ";
  357. CompileAndVerify(source, expectedOutput: expected);
  358. }
  359. [Fact]
  360. public void AsyncWithTernary()
  361. {
  362. var source = @"
  363. using System;
  364. using System.Threading.Tasks;
  365. class Test
  366. {
  367. public static Task<T> F<T>(T x)
  368. {
  369. Console.WriteLine(""F("" + x + "")"");
  370. return Task.Factory.StartNew(() => { return x; });
  371. }
  372. public static async Task<int> G(bool b1, bool b2)
  373. {
  374. int c = 0;
  375. c = c + (b1 ? 1 : await F(2));
  376. c = c + (b2 ? await F(4) : 8);
  377. return await F(c);
  378. }
  379. public static int H(bool b1, bool b2)
  380. {
  381. Task<int> t = G(b1, b2);
  382. t.Wait(1000 * 60);
  383. return t.Result;
  384. }
  385. public static void Main()
  386. {
  387. Console.WriteLine(H(false, false));
  388. Console.WriteLine(H(false, true));
  389. Console.WriteLine(H(true, false));
  390. Console.WriteLine(H(true, true));
  391. }
  392. }";
  393. var expected = @"
  394. F(2)
  395. F(10)
  396. 10
  397. F(2)
  398. F(4)
  399. F(6)
  400. 6
  401. F(9)
  402. 9
  403. F(4)
  404. F(5)
  405. 5
  406. ";
  407. CompileAndVerify(source, expectedOutput: expected);
  408. }
  409. [Fact]
  410. public void AsyncWithAnd()
  411. {
  412. var source = @"
  413. using System;
  414. using System.Threading.Tasks;
  415. class Test
  416. {
  417. public static Task<T> F<T>(T x)
  418. {
  419. Console.WriteLine(""F("" + x + "")"");
  420. return Task.Factory.StartNew(() => { return x; });
  421. }
  422. public static async Task<int> G(bool b1, bool b2)
  423. {
  424. bool x1 = b1 && await F(true);
  425. bool x2 = b1 && await F(false);
  426. bool x3 = b2 && await F(true);
  427. bool x4 = b2 && await F(false);
  428. int c = 0;
  429. if (x1) c += 1;
  430. if (x2) c += 2;
  431. if (x3) c += 4;
  432. if (x4) c += 8;
  433. return await F(c);
  434. }
  435. public static int H(bool b1, bool b2)
  436. {
  437. Task<int> t = G(b1, b2);
  438. t.Wait(1000 * 60);
  439. return t.Result;
  440. }
  441. public static void Main()
  442. {
  443. Console.WriteLine(H(false, true));
  444. }
  445. }";
  446. var expected = @"
  447. F(True)
  448. F(False)
  449. F(4)
  450. 4
  451. ";
  452. CompileAndVerify(source, expectedOutput: expected);
  453. }
  454. [Fact]
  455. public void AsyncWithOr()
  456. {
  457. var source = @"
  458. using System;
  459. using System.Threading.Tasks;
  460. class Test
  461. {
  462. public static Task<T> F<T>(T x)
  463. {
  464. Console.WriteLine(""F("" + x + "")"");
  465. return Task.Factory.StartNew(() => { return x; });
  466. }
  467. public static async Task<int> G(bool b1, bool b2)
  468. {
  469. bool x1 = b1 || await F(true);
  470. bool x2 = b1 || await F(false);
  471. bool x3 = b2 || await F(true);
  472. bool x4 = b2 || await F(false);
  473. int c = 0;
  474. if (x1) c += 1;
  475. if (x2) c += 2;
  476. if (x3) c += 4;
  477. if (x4) c += 8;
  478. return await F(c);
  479. }
  480. public static int H(bool b1, bool b2)
  481. {
  482. Task<int> t = G(b1, b2);
  483. t.Wait(1000 * 60);
  484. return t.Result;
  485. }
  486. public static void Main()
  487. {
  488. Console.WriteLine(H(false, true));
  489. }
  490. }";
  491. var expected = @"
  492. F(True)
  493. F(False)
  494. F(13)
  495. 13
  496. ";
  497. CompileAndVerify(source, expectedOutput: expected);
  498. }
  499. [Fact]
  500. public void AsyncWithCoalesce()
  501. {
  502. var source = @"
  503. using System;
  504. using System.Threading.Tasks;
  505. class Test
  506. {
  507. public static Task<string> F(string x)
  508. {
  509. Console.WriteLine(""F("" + (x ?? ""null"") + "")"");
  510. return Task.Factory.StartNew(() => { return x; });
  511. }
  512. public static async Task<string> G(string s1, string s2)
  513. {
  514. var result = await F(s1) ?? await F(s2);
  515. Console.WriteLine("" "" + (result ?? ""null""));
  516. return result;
  517. }
  518. public static string H(string s1, string s2)
  519. {
  520. Task<string> t = G(s1, s2);
  521. t.Wait(1000 * 60);
  522. return t.Result;
  523. }
  524. public static void Main()
  525. {
  526. H(null, null);
  527. H(null, ""a"");
  528. H(""b"", null);
  529. H(""c"", ""d"");
  530. }
  531. }";
  532. var expected = @"
  533. F(null)
  534. F(null)
  535. null
  536. F(null)
  537. F(a)
  538. a
  539. F(b)
  540. b
  541. F(c)
  542. c
  543. ";
  544. CompileAndVerify(source, expectedOutput: expected);
  545. }
  546. [Fact]
  547. public void AsyncWithParam()
  548. {
  549. var source = @"
  550. using System;
  551. using System.Threading.Tasks;
  552. class Test
  553. {
  554. public static async Task<int> G(int x)
  555. {
  556. await Task.Factory.StartNew(() => { return x; });
  557. x += 21;
  558. await Task.Factory.StartNew(() => { return x; });
  559. x += 21;
  560. return x;
  561. }
  562. public static void Main()
  563. {
  564. Task<int> t = G(0);
  565. t.Wait(1000 * 60);
  566. Console.WriteLine(t.Result);
  567. }
  568. }";
  569. var expected = @"
  570. 42
  571. ";
  572. CompileAndVerify(source, expectedOutput: expected);
  573. }
  574. [Fact]
  575. public void AwaitInExpr()
  576. {
  577. var source = @"
  578. using System;
  579. using System.Threading.Tasks;
  580. class Test
  581. {
  582. public static async Task<int> F()
  583. {
  584. return await Task.Factory.StartNew(() => 21);
  585. }
  586. public static async Task<int> G()
  587. {
  588. int c = 0;
  589. c = (await F()) + 21;
  590. return c;
  591. }
  592. public static void Main()
  593. {
  594. Task<int> t = G();
  595. t.Wait(1000 * 60);
  596. Console.WriteLine(t.Result);
  597. }
  598. }";
  599. var expected = @"
  600. 42
  601. ";
  602. CompileAndVerify(source, expectedOutput: expected);
  603. }
  604. [Fact]
  605. public void AsyncWithParamsAndLocals_UnHoisted()
  606. {
  607. var source = @"
  608. using System;
  609. using System.Threading.Tasks;
  610. class Test
  611. {
  612. public static async Task<int> F(int x)
  613. {
  614. return await Task.Factory.StartNew(() => { return x; });
  615. }
  616. public static async Task<int> G(int x)
  617. {
  618. int c = 0;
  619. c = await F(x);
  620. return c;
  621. }
  622. public static void Main()
  623. {
  624. Task<int> t = G(21);
  625. t.Wait(1000 * 60);
  626. Console.WriteLine(t.Result);
  627. }
  628. }";
  629. var expected = @"
  630. 21
  631. ";
  632. CompileAndVerify(source, expectedOutput: expected);
  633. }
  634. [Fact]
  635. public void AsyncWithParamsAndLocals_Hoisted()
  636. {
  637. var source = @"
  638. using System;
  639. using System.Threading.Tasks;
  640. class Test
  641. {
  642. public static async Task<int> F(int x)
  643. {
  644. return await Task.Factory.StartNew(() => { return x; });
  645. }
  646. public static async Task<int> G(int x)
  647. {
  648. int c = 0;
  649. c = await F(x);
  650. return c;
  651. }
  652. public static void Main()
  653. {
  654. Task<int> t = G(21);
  655. t.Wait(1000 * 60);
  656. Console.WriteLine(t.Result);
  657. }
  658. }";
  659. var expected = @"
  660. 21
  661. ";
  662. CompileAndVerify(source, expectedOutput: expected);
  663. }
  664. [Fact]
  665. public void AsyncWithParamsAndLocals_DoubleAwait_Spilling()
  666. {
  667. var source = @"
  668. using System;
  669. using System.Threading.Tasks;
  670. class Test
  671. {
  672. public static async Task<int> F(int x)
  673. {
  674. return await Task.Factory.StartNew(() => { return x; });
  675. }
  676. public static async Task<int> G(int x)
  677. {
  678. int c = 0;
  679. c = (await F(x)) + c;
  680. c = (await F(x)) + c;
  681. return c;
  682. }
  683. public static void Main()
  684. {
  685. Task<int> t = G(21);
  686. t.Wait(1000 * 60);
  687. Console.WriteLine(t.Result);
  688. }
  689. }";
  690. var expected = @"
  691. 42
  692. ";
  693. // When the local 'c' gets hoisted, the statement:
  694. // c = (await F(x)) + c;
  695. // Gets rewritten to:
  696. // this.c_field = (await F(x)) + this.c_field;
  697. //
  698. // The code-gen for the assignment is something like this:
  699. // ldarg0 // load the 'this' reference to the stack
  700. // <emitted await expression>
  701. // stfld
  702. //
  703. // What we really want is to evaluate any parts of the lvalue that have side-effects (which is this case is
  704. // nothing), and then defer loading the address for the field reference until after the await expression:
  705. // <emitted await expression>
  706. // <store to tmp>
  707. // ldarg0
  708. // <load tmp>
  709. // stfld
  710. //
  711. // So this case actually requires stack spilling, which is not yet implemented. This has the unfortunate
  712. // consequence of preventing await expressions from being assigned to hoisted locals.
  713. //
  714. CompileAndVerify(source, expectedOutput: expected);
  715. }
  716. [Fact]
  717. public void AsyncWithDynamic()
  718. {
  719. var source = @"
  720. using System;
  721. using System.Threading.Tasks;
  722. class Test
  723. {
  724. public static async Task<int> F(dynamic t)
  725. {
  726. return await t;
  727. }
  728. public static void Main()
  729. {
  730. Task<int> t = F(Task.Factory.StartNew(() => { return 42; }));
  731. t.Wait(1000 * 60);
  732. Console.WriteLine(t.Result);
  733. }
  734. }";
  735. var expected = @"
  736. 42
  737. ";
  738. CompileAndVerify(source, expectedOutput: expected, references: new[] { CSharpRef });
  739. }
  740. [Fact]
  741. public void AsyncWithThisRef()
  742. {
  743. var source = @"
  744. using System;
  745. using System.Threading.Tasks;
  746. class C
  747. {
  748. int x = 42;
  749. public async Task<int> F()
  750. {
  751. int c = this.x;
  752. return await Task.Factory.StartNew(() => c);
  753. }
  754. }
  755. class Test
  756. {
  757. public static void Main()
  758. {
  759. Task<int> t = new C().F();
  760. t.Wait(1000 * 60);
  761. Console.WriteLine(t.Result);
  762. }
  763. }";
  764. var expected = @"
  765. 42
  766. ";
  767. CompileAndVerify(source, expectedOutput: expected);
  768. }
  769. [Fact]
  770. public void AsyncWithBaseRef()
  771. {
  772. var source = @"
  773. using System;
  774. using System.Threading.Tasks;
  775. class B
  776. {
  777. protected int x = 42;
  778. }
  779. class C : B
  780. {
  781. public async Task<int> F()
  782. {
  783. int c = base.x;
  784. return await Task.Factory.StartNew(() => c);
  785. }
  786. }
  787. class Test
  788. {
  789. public static void Main()
  790. {
  791. Task<int> t = new C().F();
  792. t.Wait(1000 * 60);
  793. Console.WriteLine(t.Result);
  794. }
  795. }";
  796. var expected = @"
  797. 42
  798. ";
  799. CompileAndVerify(source, expectedOutput: expected);
  800. }
  801. [Fact]
  802. public void AsyncWithException1()
  803. {
  804. var source = @"
  805. using System;
  806. using System.Threading.Tasks;
  807. class Test
  808. {
  809. static async Task<int> F()
  810. {
  811. throw new Exception();
  812. }
  813. static async Task<int> G()
  814. {
  815. try
  816. {
  817. return await F();
  818. }
  819. catch(Exception)
  820. {
  821. return -1;
  822. }
  823. }
  824. public static void Main()
  825. {
  826. Task<int> t2 = G();
  827. t2.Wait(1000 * 60);
  828. Console.WriteLine(t2.Result);
  829. }
  830. }";
  831. var expected = @"
  832. -1
  833. ";
  834. CompileAndVerify(source, expectedOutput: expected);
  835. }
  836. [Fact]
  837. public void AsyncWithException2()
  838. {
  839. var source = @"
  840. using System;
  841. using System.Threading.Tasks;
  842. class Test
  843. {
  844. static async Task<int> F()
  845. {
  846. throw new Exception();
  847. }
  848. static async Task<int> H()
  849. {
  850. return await F();
  851. }
  852. public static void Main()
  853. {
  854. Task<int> t1 = H();
  855. try
  856. {
  857. t1.Wait(1000 * 60);
  858. }
  859. catch (AggregateException)
  860. {
  861. Console.WriteLine(""exception"");
  862. }
  863. }
  864. }";
  865. var expected = @"
  866. exception
  867. ";
  868. CompileAndVerify(source, expectedOutput: expected);
  869. }
  870. [Fact]
  871. public void AsyncInFinally001()
  872. {
  873. var source = @"
  874. using System;
  875. using System.Threading.Tasks;
  876. class Test
  877. {
  878. static async Task<int> F()
  879. {
  880. return 2;
  881. }
  882. static async Task<int> G()
  883. {
  884. int x = 42;
  885. try
  886. {
  887. }
  888. finally
  889. {
  890. x = await F();
  891. }
  892. return x;
  893. }
  894. public static void Main()
  895. {
  896. Task<int> t2 = G();
  897. t2.Wait(1000 * 60);
  898. Console.WriteLine(t2.Result);
  899. }
  900. }";
  901. var expected = @"
  902. 2
  903. ";
  904. CompileAndVerify(source, expectedOutput: expected).
  905. VerifyIL("Test.<G>d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
  906. {
  907. // Code size 229 (0xe5)
  908. .maxstack 3
  909. .locals init (int V_0,
  910. int V_1,
  911. object V_2,
  912. System.Runtime.CompilerServices.TaskAwaiter<int> V_3,
  913. object V_4,
  914. System.Exception V_5)
  915. IL_0000: ldarg.0
  916. IL_0001: ldfld ""int Test.<G>d__1.<>1__state""
  917. IL_0006: stloc.0
  918. .try
  919. {
  920. IL_0007: ldloc.0
  921. IL_0008: brfalse.s IL_000e
  922. IL_000a: ldloc.0
  923. IL_000b: ldc.i4.1
  924. IL_000c: beq.s IL_005f
  925. IL_000e: ldarg.0
  926. IL_000f: ldnull
  927. IL_0010: stfld ""object Test.<G>d__1.<>7__wrap1""
  928. IL_0015: ldarg.0
  929. IL_0016: ldc.i4.0
  930. IL_0017: stfld ""int Test.<G>d__1.<>7__wrap2""
  931. .try
  932. {
  933. IL_001c: leave.s IL_0028
  934. }
  935. catch object
  936. {
  937. IL_001e: stloc.2
  938. IL_001f: ldarg.0
  939. IL_0020: ldloc.2
  940. IL_0021: stfld ""object Test.<G>d__1.<>7__wrap1""
  941. IL_0026: leave.s IL_0028
  942. }
  943. IL_0028: call ""System.Threading.Tasks.Task<int> Test.F()""
  944. IL_002d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
  945. IL_0032: stloc.3
  946. IL_0033: ldloca.s V_3
  947. IL_0035: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
  948. IL_003a: brtrue.s IL_007b
  949. IL_003c: ldarg.0
  950. IL_003d: ldc.i4.1
  951. IL_003e: dup
  952. IL_003f: stloc.0
  953. IL_0040: stfld ""int Test.<G>d__1.<>1__state""
  954. IL_0045: ldarg.0
  955. IL_0046: ldloc.3
  956. IL_0047: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  957. IL_004c: ldarg.0
  958. IL_004d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  959. IL_0052: ldloca.s V_3
  960. IL_0054: ldarg.0
  961. IL_0055: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Test.<G>d__1>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Test.<G>d__1)""
  962. IL_005a: leave IL_00e4
  963. IL_005f: ldarg.0
  964. IL_0060: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  965. IL_0065: stloc.3
  966. IL_0066: ldarg.0
  967. IL_0067: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  968. IL_006c: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
  969. IL_0072: ldarg.0
  970. IL_0073: ldc.i4.m1
  971. IL_0074: dup
  972. IL_0075: stloc.0
  973. IL_0076: stfld ""int Test.<G>d__1.<>1__state""
  974. IL_007b: ldloca.s V_3
  975. IL_007d: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
  976. IL_0082: ldloca.s V_3
  977. IL_0084: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
  978. IL_008a: ldarg.0
  979. IL_008b: ldfld ""object Test.<G>d__1.<>7__wrap1""
  980. IL_0090: stloc.s V_4
  981. IL_0092: ldloc.s V_4
  982. IL_0094: brfalse.s IL_00ad
  983. IL_0096: ldloc.s V_4
  984. IL_0098: isinst ""System.Exception""
  985. IL_009d: dup
  986. IL_009e: brtrue.s IL_00a3
  987. IL_00a0: ldloc.s V_4
  988. IL_00a2: throw
  989. IL_00a3: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)""
  990. IL_00a8: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()""
  991. IL_00ad: ldarg.0
  992. IL_00ae: ldnull
  993. IL_00af: stfld ""object Test.<G>d__1.<>7__wrap1""
  994. IL_00b4: stloc.1
  995. IL_00b5: leave.s IL_00d0
  996. }
  997. catch System.Exception
  998. {
  999. IL_00b7: stloc.s V_5
  1000. IL_00b9: ldarg.0
  1001. IL_00ba: ldc.i4.s -2
  1002. IL_00bc: stfld ""int Test.<G>d__1.<>1__state""
  1003. IL_00c1: ldarg.0
  1004. IL_00c2: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  1005. IL_00c7: ldloc.s V_5
  1006. IL_00c9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
  1007. IL_00ce: leave.s IL_00e4
  1008. }
  1009. IL_00d0: ldarg.0
  1010. IL_00d1: ldc.i4.s -2
  1011. IL_00d3: stfld ""int Test.<G>d__1.<>1__state""
  1012. IL_00d8: ldarg.0
  1013. IL_00d9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  1014. IL_00de: ldloc.1
  1015. IL_00df: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
  1016. IL_00e4: ret
  1017. }
  1018. ");
  1019. }
  1020. [Fact]
  1021. public void AsyncInFinally002()
  1022. {
  1023. var source = @"
  1024. using System;
  1025. using System.Threading.Tasks;
  1026. class Test
  1027. {
  1028. static async Task<int> F()
  1029. {
  1030. System.Console.Write(""F"");
  1031. return 2;
  1032. }
  1033. static async Task G()
  1034. {
  1035. int x = 0;
  1036. try
  1037. {
  1038. throw new Exception(""hello"");
  1039. }
  1040. finally
  1041. {
  1042. x += await F();
  1043. }
  1044. }
  1045. public static void Main()
  1046. {
  1047. Task t2 = G();
  1048. try
  1049. {
  1050. t2.Wait(1000 * 60);
  1051. }
  1052. catch (Exception ex)
  1053. {
  1054. Console.WriteLine(ex.Message);
  1055. }
  1056. }
  1057. }";
  1058. var expected = @"FOne or more errors occurred.
  1059. ";
  1060. CompileAndVerify(source, expectedOutput: expected);
  1061. }
  1062. [Fact]
  1063. public void AsyncInFinally003()
  1064. {
  1065. var source = @"
  1066. using System;
  1067. using System.Threading.Tasks;
  1068. class Test
  1069. {
  1070. static async Task<int> F()
  1071. {
  1072. return 2;
  1073. }
  1074. static async Task<int> G()
  1075. {
  1076. int x = 0;
  1077. try
  1078. {
  1079. x = await F();
  1080. return x;
  1081. }
  1082. finally
  1083. {
  1084. x += await F();
  1085. }
  1086. }
  1087. public static void Main()
  1088. {
  1089. Task<int> t2 = G();
  1090. t2.Wait(1000 * 60);
  1091. Console.WriteLine(t2.Result);
  1092. }
  1093. }";
  1094. var expected = @"
  1095. 2
  1096. ";
  1097. CompileAndVerify(source, expectedOutput: expected);
  1098. }
  1099. [Fact]
  1100. public void AsyncInFinally004()
  1101. {
  1102. var source = @"
  1103. using System;
  1104. using System.Threading.Tasks;
  1105. class Test
  1106. {
  1107. static async Task<int> F()
  1108. {
  1109. return 2;
  1110. }
  1111. static async Task<int> G()
  1112. {
  1113. int x = 0;
  1114. try
  1115. {
  1116. try
  1117. {
  1118. throw new Exception();
  1119. }
  1120. finally
  1121. {
  1122. x += await F();
  1123. }
  1124. }
  1125. catch
  1126. {
  1127. return x;
  1128. }
  1129. }
  1130. public static void Main()
  1131. {
  1132. Task<int> t2 = G();
  1133. t2.Wait(1000 * 60);
  1134. Console.WriteLine(t2.Result);
  1135. }
  1136. }";
  1137. var expected = @"
  1138. 2
  1139. ";
  1140. CompileAndVerify(source, expectedOutput: expected);
  1141. }
  1142. [Fact]
  1143. public void AsyncInFinallyNested001()
  1144. {
  1145. var source = @"
  1146. using System;
  1147. using System.Threading.Tasks;
  1148. class Test
  1149. {
  1150. static async Task<int> F(int a)
  1151. {
  1152. await Task.Yield();
  1153. return a;
  1154. }
  1155. static async Task<int> G()
  1156. {
  1157. int x = 0;
  1158. try
  1159. {
  1160. try
  1161. {
  1162. x = await F(1);
  1163. goto L1;
  1164. System.Console.WriteLine(""FAIL"");
  1165. }
  1166. finally
  1167. {
  1168. x += await F(2);
  1169. }
  1170. }
  1171. finally
  1172. {
  1173. try
  1174. {
  1175. x += await F(4);
  1176. }
  1177. finally
  1178. {
  1179. x += await F(8);
  1180. }
  1181. }
  1182. System.Console.WriteLine(""FAIL"");
  1183. L1:
  1184. return x;
  1185. }
  1186. public static void Main()
  1187. {
  1188. Task<int> t2 = G();
  1189. t2.Wait(1000 * 60);
  1190. Console.WriteLine(t2.Result);
  1191. }
  1192. }";
  1193. var expected = @"15";
  1194. CompileAndVerify(source, expectedOutput: expected);
  1195. }
  1196. [Fact]
  1197. public void AsyncInFinallyNested002()
  1198. {
  1199. var source = @"
  1200. using System;
  1201. using System.Threading.Tasks;
  1202. class Test
  1203. {
  1204. static async Task<int> F(int a)
  1205. {
  1206. await Task.Yield();
  1207. return a;
  1208. }
  1209. static async Task<int> G()
  1210. {
  1211. int x = 0;
  1212. try
  1213. {
  1214. try
  1215. {
  1216. try
  1217. {
  1218. x = await F(1);
  1219. throw new Exception(""hello"");
  1220. System.Console.WriteLine(""FAIL"");
  1221. }
  1222. finally
  1223. {
  1224. x += await F(2);
  1225. }
  1226. System.Console.WriteLine(""FAIL"");
  1227. }
  1228. finally
  1229. {
  1230. try
  1231. {
  1232. x += await F(4);
  1233. }
  1234. finally
  1235. {
  1236. x += await F(8);
  1237. }
  1238. }
  1239. System.Console.WriteLine(""FAIL"");
  1240. }
  1241. catch(Exception ex)
  1242. {
  1243. System.Console.WriteLine(ex.Message);
  1244. }
  1245. return x;
  1246. }
  1247. public static void Main()
  1248. {
  1249. Task<int> t2 = G();
  1250. t2.Wait(1000 * 60);
  1251. Console.WriteLine(t2.Result);
  1252. }
  1253. }";
  1254. var expected = @"hello
  1255. 15";
  1256. CompileAndVerify(source, expectedOutput: expected);
  1257. }
  1258. [Fact]
  1259. public void AsyncInFinallyNested003()
  1260. {
  1261. var source = @"
  1262. using System;
  1263. using System.Threading.Tasks;
  1264. class Test
  1265. {
  1266. static async Task<int> F(int a)
  1267. {
  1268. await Task.Yield();
  1269. return a;
  1270. }
  1271. static async Task<int> G()
  1272. {
  1273. int x = 0;
  1274. try
  1275. {
  1276. try
  1277. {
  1278. try
  1279. {
  1280. x = await F(1);
  1281. throw new Exception(""hello"");
  1282. System.Console.WriteLine(""FAIL"");
  1283. }
  1284. finally
  1285. {
  1286. x += await F(2);
  1287. }
  1288. System.Console.WriteLine(""FAIL"");
  1289. }
  1290. finally
  1291. {
  1292. try
  1293. {
  1294. x += await F(4);
  1295. }
  1296. finally
  1297. {
  1298. x += await F(8);
  1299. throw new Exception(""bye"");
  1300. }
  1301. }
  1302. System.Console.WriteLine(""FAIL"");
  1303. }
  1304. catch(Exception ex)
  1305. {
  1306. System.Console.WriteLine(ex.Message);
  1307. }
  1308. return x;
  1309. }
  1310. public static void Main()
  1311. {
  1312. Task<int> t2 = G();
  1313. t2.Wait(1000 * 60);
  1314. Console.WriteLine(t2.Result);
  1315. }
  1316. }";
  1317. var expected = @"bye
  1318. 15";
  1319. CompileAndVerify(source, expectedOutput: expected);
  1320. }
  1321. [Fact]
  1322. public void AsyncInCatch001()
  1323. {
  1324. var source = @"
  1325. using System;
  1326. using System.Threading.Tasks;
  1327. class Test
  1328. {
  1329. static async Task<int> F()
  1330. {
  1331. return 2;
  1332. }
  1333. static async Task<int> G()
  1334. {
  1335. int x = 0;
  1336. try
  1337. {
  1338. x = x / x;
  1339. }
  1340. catch
  1341. {
  1342. x = await F();
  1343. }
  1344. return x;
  1345. }
  1346. public static void Main()
  1347. {
  1348. Task<int> t2 = G();
  1349. t2.Wait(1000 * 60);
  1350. Console.WriteLine(t2.Result);
  1351. }
  1352. }";
  1353. var expected = @"
  1354. 2
  1355. ";
  1356. CompileAndVerify(source, expectedOutput: expected).
  1357. VerifyIL("Test.<G>d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
  1358. {
  1359. // Code size 182 (0xb6)
  1360. .maxstack 3
  1361. .locals init (int V_0,
  1362. int V_1,
  1363. int V_2, //x
  1364. int V_3,
  1365. System.Runtime.CompilerServices.TaskAwaiter<int> V_4,
  1366. System.Exception V_5)
  1367. IL_0000: ldarg.0
  1368. IL_0001: ldfld ""int Test.<G>d__1.<>1__state""
  1369. IL_0006: stloc.0
  1370. .try
  1371. {
  1372. IL_0007: ldloc.0
  1373. IL_0008: brfalse.s IL_000e
  1374. IL_000a: ldloc.0
  1375. IL_000b: ldc.i4.1
  1376. IL_000c: beq.s IL_0057
  1377. IL_000e: ldc.i4.0
  1378. IL_000f: stloc.2
  1379. IL_0010: ldc.i4.0
  1380. IL_0011: stloc.3
  1381. .try
  1382. {
  1383. IL_0012: ldloc.2
  1384. IL_0013: dup
  1385. IL_0014: div
  1386. IL_0015: stloc.2
  1387. IL_0016: leave.s IL_001d
  1388. }
  1389. catch object
  1390. {
  1391. IL_0018: pop
  1392. IL_0019: ldc.i4.1
  1393. IL_001a: stloc.3
  1394. IL_001b: leave.s IL_001d
  1395. }
  1396. IL_001d: ldloc.3
  1397. IL_001e: ldc.i4.1
  1398. IL_001f: bne.un.s IL_0084
  1399. IL_0021: call ""System.Threading.Tasks.Task<int> Test.F()""
  1400. IL_0026: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
  1401. IL_002b: stloc.s V_4
  1402. IL_002d: ldloca.s V_4
  1403. IL_002f: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
  1404. IL_0034: brtrue.s IL_0074
  1405. IL_0036: ldarg.0
  1406. IL_0037: ldc.i4.1
  1407. IL_0038: dup
  1408. IL_0039: stloc.0
  1409. IL_003a: stfld ""int Test.<G>d__1.<>1__state""
  1410. IL_003f: ldarg.0
  1411. IL_0040: ldloc.s V_4
  1412. IL_0042: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  1413. IL_0047: ldarg.0
  1414. IL_0048: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  1415. IL_004d: ldloca.s V_4
  1416. IL_004f: ldarg.0
  1417. IL_0050: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Test.<G>d__1>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Test.<G>d__1)""
  1418. IL_0055: leave.s IL_00b5
  1419. IL_0057: ldarg.0
  1420. IL_0058: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  1421. IL_005d: stloc.s V_4
  1422. IL_005f: ldarg.0
  1423. IL_0060: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Test.<G>d__1.<>u__$awaiter0""
  1424. IL_0065: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
  1425. IL_006b: ldarg.0
  1426. IL_006c: ldc.i4.m1
  1427. IL_006d: dup
  1428. IL_006e: stloc.0
  1429. IL_006f: stfld ""int Test.<G>d__1.<>1__state""
  1430. IL_0074: ldloca.s V_4
  1431. IL_0076: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
  1432. IL_007b: ldloca.s V_4
  1433. IL_007d: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
  1434. IL_0083: stloc.2
  1435. IL_0084: ldloc.2
  1436. IL_0085: stloc.1
  1437. IL_0086: leave.s IL_00a1
  1438. }
  1439. catch System.Exception
  1440. {
  1441. IL_0088: stloc.s V_5
  1442. IL_008a: ldarg.0
  1443. IL_008b: ldc.i4.s -2
  1444. IL_008d: stfld ""int Test.<G>d__1.<>1__state""
  1445. IL_0092: ldarg.0
  1446. IL_0093: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  1447. IL_0098: ldloc.s V_5
  1448. IL_009a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetException(System.Exception)""
  1449. IL_009f: leave.s IL_00b5
  1450. }
  1451. IL_00a1: ldarg.0
  1452. IL_00a2: ldc.i4.s -2
  1453. IL_00a4: stfld ""int Test.<G>d__1.<>1__state""
  1454. IL_00a9: ldarg.0
  1455. IL_00aa: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int> Test.<G>d__1.<>t__builder""
  1456. IL_00af: ldloc.1
  1457. IL_00b0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.SetResult(int)""
  1458. IL_00b5: ret
  1459. }
  1460. ");
  1461. }
  1462. [Fact]
  1463. public void AsyncInCatchRethrow()
  1464. {
  1465. var source = @"
  1466. using System;
  1467. using System.Threading.Tasks;
  1468. class Test
  1469. {
  1470. static async Task<int> F()
  1471. {
  1472. await Task.Yield();
  1473. return 2;
  1474. }
  1475. static async Task<int> G()
  1476. {
  1477. int x = 0;
  1478. try
  1479. {
  1480. try
  1481. {
  1482. x = x / x;
  1483. }
  1484. catch
  1485. {
  1486. x = await F();
  1487. throw;
  1488. }
  1489. }
  1490. catch(DivideByZeroException ex)
  1491. {
  1492. x = await F();
  1493. System.Console.WriteLine(ex.Message);
  1494. }
  1495. return x;
  1496. }
  1497. public static void Main()
  1498. {
  1499. Task<int> t2 = G();
  1500. t2.Wait(1000 * 60);
  1501. Console.WriteLine(t2.Result);
  1502. }
  1503. }";
  1504. var expected = @"
  1505. Attempted to divide by zero.
  1506. 2
  1507. ";
  1508. CompileAndVerify(source, expectedOutput: expected);
  1509. }
  1510. [Fact]
  1511. public void AsyncInCatchFilter()
  1512. {
  1513. var source = @"
  1514. using System;
  1515. using System.Threading.Tasks;
  1516. class Test
  1517. {
  1518. static async Task<int> F()
  1519. {
  1520. await Task.Yield();
  1521. return 2;
  1522. }
  1523. static async Task<int> G()
  1524. {
  1525. int x = 0;
  1526. try
  1527. {
  1528. try
  1529. {
  1530. x = x / x;
  1531. }
  1532. catch if(x != 0)
  1533. {
  1534. x = await F();
  1535. throw;
  1536. }
  1537. }
  1538. catch(Exception ex) if(x == 0 && ((ex = new Exception(""hello"")) != null))
  1539. {
  1540. x = await F();
  1541. System.Console.WriteLine(ex.Message);
  1542. }
  1543. return x;
  1544. }
  1545. public static void Main()
  1546. {
  1547. Task<int> t2 = G();
  1548. t2.Wait(1000 * 60);
  1549. Console.WriteLine(t2.Result);
  1550. }
  1551. }";
  1552. var expected = @"
  1553. hello
  1554. 2
  1555. ";
  1556. CompileAndVerify(source, expectedOutput: expected);
  1557. }
  1558. [Fact]
  1559. public void AsyncInCatchFilterLifted()
  1560. {
  1561. var source = @"
  1562. using System;
  1563. using System.Threading.Tasks;
  1564. class Test
  1565. {
  1566. static async Task<int> F()
  1567. {
  1568. await Task.Yield();
  1569. return 2;
  1570. }
  1571. static bool T(Func<bool> f, ref Exception ex)
  1572. {
  1573. var result = f();
  1574. ex = new Exception(result.ToString());
  1575. return result;
  1576. }
  1577. static async Task<int> G()
  1578. {
  1579. int x = 0;
  1580. try
  1581. {
  1582. x = x / x;
  1583. }
  1584. catch(Exception ex) if(T(()=>ex.Message == null, ref ex))
  1585. {
  1586. x = await F();
  1587. System.Console.WriteLine(ex.Message);
  1588. }
  1589. catch(Exception ex) if(T(()=>ex.Message != null, ref ex))
  1590. {
  1591. x = await F();
  1592. System.Console.WriteLine(ex.Message);
  1593. }
  1594. return x;
  1595. }
  1596. public static void Main()
  1597. {
  1598. Task<int> t2 = G();
  1599. t2.Wait(1000 * 60);
  1600. Console.WriteLine(t2.Result);
  1601. }
  1602. }";
  1603. var expected = @"True
  1604. 2
  1605. ";
  1606. CompileAndVerify(source, expectedOutput: expected);
  1607. }
  1608. [Fact]
  1609. public void AsyncInCatchFinallyMixed()
  1610. {
  1611. var source = @"
  1612. using System;
  1613. using System.Threading.Tasks;
  1614. class Test
  1615. {
  1616. static async Task<int> F(int x)
  1617. {
  1618. await Task.Yield();
  1619. return x;
  1620. }
  1621. static async Task<int> G()
  1622. {
  1623. int x = 0;
  1624. try
  1625. {
  1626. try
  1627. {
  1628. for (int i = 0; i < 5; i++)
  1629. {
  1630. try
  1631. {
  1632. try
  1633. {
  1634. x = x / await F(0);
  1635. }
  1636. catch (DivideByZeroException) if (i < 3)
  1637. {
  1638. await Task.Yield();
  1639. continue;
  1640. }
  1641. catch (DivideByZeroException)
  1642. {
  1643. x = 2 + await F(x);
  1644. throw;
  1645. }
  1646. System.Console.WriteLine(""FAIL"");
  1647. }
  1648. finally
  1649. {
  1650. x = await F(x) + 3;
  1651. if (i >= 3)
  1652. {
  1653. throw new Exception(""hello"");
  1654. }
  1655. }
  1656. }
  1657. }
  1658. finally
  1659. {
  1660. x = 11 + await F(x);
  1661. }
  1662. }
  1663. catch (Exception ex)
  1664. {
  1665. x = await F(x) + 17;
  1666. System.Console.WriteLine(ex.Message);
  1667. }
  1668. return x;
  1669. }
  1670. public static void Main()
  1671. {
  1672. Task<int> t2 = G();
  1673. t2.Wait(1000 * 60);
  1674. Console.WriteLine(t2.Result);
  1675. }
  1676. }";
  1677. var expected = @"
  1678. hello
  1679. 42
  1680. ";
  1681. CompileAndVerify(source, expectedOutput: expected);
  1682. }
  1683. [Fact]
  1684. public void AsyncInCatchFinallyMixed_InAsyncLambda()
  1685. {
  1686. var source = @"
  1687. using System;
  1688. using System.Threading.Tasks;
  1689. class Test
  1690. {
  1691. static async Task<int> F(int x)
  1692. {
  1693. await Task.Yield();
  1694. return x;
  1695. }
  1696. static Func<Task<int>> G()
  1697. {
  1698. int x = 0;
  1699. return async () =>
  1700. {
  1701. try
  1702. {
  1703. try
  1704. {
  1705. for (int i = 0; i < 5; i++)
  1706. {
  1707. try
  1708. {
  1709. try
  1710. {
  1711. x = x / await F(0);
  1712. }
  1713. catch (DivideByZeroException) if (i < 3)
  1714. {
  1715. await Task.Yield();
  1716. continue;
  1717. }
  1718. catch (DivideByZeroException)
  1719. {
  1720. x = 2 + await F(x);
  1721. throw;
  1722. }
  1723. System.Console.WriteLine(""FAIL"");
  1724. }
  1725. finally
  1726. {
  1727. x = await F(x) + 3;
  1728. if (i >= 3)
  1729. {
  1730. throw new Exception(""hello"");
  1731. }
  1732. }
  1733. }
  1734. }
  1735. finally
  1736. {
  1737. x = 11 + await F(x);
  1738. }
  1739. }
  1740. catch (Exception ex)
  1741. {
  1742. x = await F(x) + 17;
  1743. System.Console.WriteLine(ex.Message);
  1744. }
  1745. return x;
  1746. };
  1747. }
  1748. public static void Main()
  1749. {
  1750. Task<int> t2 = G()();
  1751. t2.Wait(1000 * 60);
  1752. Console.WriteLine(t2.Result);
  1753. }
  1754. }";
  1755. var expected = @"
  1756. hello
  1757. 42
  1758. ";
  1759. CompileAndVerify(source, expectedOutput: expected);
  1760. }
  1761. [Fact]
  1762. public void AsyncInConditionalAccess()
  1763. {
  1764. var source = @"
  1765. using System;
  1766. using System.Collections.Generic;
  1767. using System.Threading.Tasks;
  1768. class Test
  1769. {
  1770. class C1
  1771. {
  1772. public int M(int x)
  1773. {
  1774. return x;
  1775. }
  1776. }
  1777. public static int Get(int x)
  1778. {
  1779. Console.WriteLine(""> "" + x);
  1780. return x;
  1781. }
  1782. public static async Task<int> F(int x)
  1783. {
  1784. return await Task.Factory.StartNew(() => x);
  1785. }
  1786. public static async Task<int?> G()
  1787. {
  1788. var c = new C1();
  1789. return c?.M(await F(Get(42)));
  1790. }
  1791. public static void Main()
  1792. {
  1793. var t = G();
  1794. System.Console.WriteLine(t.Result);
  1795. }
  1796. }";
  1797. var expected = @"
  1798. > 42
  1799. 42";
  1800. CompileAndVerifyExperimental(source, expected);
  1801. }
  1802. [Fact]
  1803. public void Conformance_Awaiting_Methods_Generic01()
  1804. {
  1805. var source = @"
  1806. using System;
  1807. using System.Runtime.CompilerServices;
  1808. using System.Threading;
  1809. //Implementation of you own async pattern
  1810. public class MyTask<T>
  1811. {
  1812. public MyTaskAwaiter<T> GetAwaiter()
  1813. {
  1814. return new MyTaskAwaiter<T>();
  1815. }
  1816. public async void Run<U>(U u) where U : MyTask<int>, new()
  1817. {
  1818. try
  1819. {
  1820. int tests = 0;
  1821. tests++;
  1822. var rez = await u;
  1823. if (rez == 0)
  1824. Driver.Count++;
  1825. Driver.Result = Driver.Count - tests;
  1826. }
  1827. finally
  1828. {
  1829. //When test complete, set the flag.
  1830. Driver.CompletedSignal.Set();
  1831. }
  1832. }
  1833. }
  1834. public class MyTaskAwaiter<T> : INotifyCompletion
  1835. {
  1836. public void OnCompleted(Action continuationAction)
  1837. {
  1838. }
  1839. public T GetResult()
  1840. {
  1841. return default(T);
  1842. }
  1843. public bool IsCompleted { get { return true; } }
  1844. }
  1845. //-------------------------------------
  1846. class Driver
  1847. {
  1848. public static int Result = -1;
  1849. public static int Count = 0;
  1850. public static AutoResetEvent CompletedSignal = new AutoResetEvent(false);
  1851. static void Main()
  1852. {
  1853. new MyTask<int>().Run<MyTask<int>>(new MyTask<int>());
  1854. CompletedSignal.WaitOne();
  1855. // 0 - success
  1856. // 1 - failed (test completed)
  1857. // -1 - failed (test incomplete - deadlock, etc)
  1858. Console.WriteLine(Driver.Result);
  1859. }
  1860. }";
  1861. CompileAndVerify(source, "0");
  1862. }
  1863. [Fact]
  1864. public void Conformance_Awaiting_Methods_Method01()
  1865. {
  1866. var source = @"
  1867. using System.Threading;
  1868. using System.Threading.Tasks;
  1869. using System;
  1870. public interface IExplicit
  1871. {
  1872. Task Method(int x = 4);
  1873. }
  1874. class C1 : IExplicit
  1875. {
  1876. Task IExplicit.Method(int x)
  1877. {
  1878. //This will fail until Run and RunEx are merged back together
  1879. return Task.Run(async () =>
  1880. {
  1881. await Task.Delay(1);
  1882. Driver.Count++;
  1883. });
  1884. }
  1885. }
  1886. class TestCase
  1887. {
  1888. public async void Run()
  1889. {
  1890. try
  1891. {
  1892. int tests = 0;
  1893. tests++;
  1894. C1 c = new C1();
  1895. IExplicit e = (IExplicit)c;
  1896. await e.Method();
  1897. Driver.Result = Driver.Count - tests;
  1898. }
  1899. finally
  1900. {
  1901. //When test complete, set the flag.
  1902. Driver.CompletedSignal.Set();
  1903. }
  1904. }
  1905. }
  1906. class Driver
  1907. {
  1908. public static int Result = -1;
  1909. public static int Count = 0;
  1910. public static AutoResetEvent CompletedSignal = new AutoResetEvent(false);
  1911. static void Main()
  1912. {
  1913. var t = new TestCase();
  1914. t.Run();
  1915. CompletedSignal.WaitOne();
  1916. // 0 - success
  1917. // 1 - failed (test completed)
  1918. // -1 - failed (test incomplete - deadlock, etc)
  1919. Console.WriteLine(Driver.Result);
  1920. }
  1921. }";
  1922. CompileAndVerify(source, "0");
  1923. }
  1924. [Fact]
  1925. public void DoFinallyBodies()
  1926. {
  1927. var source = @"
  1928. using System.Threading.Tasks;
  1929. using System;
  1930. class Driver
  1931. {
  1932. public static int finally_count = 0;
  1933. static async Task F()
  1934. {
  1935. try
  1936. {
  1937. await Task.Factory.StartNew(() => { });
  1938. }
  1939. finally
  1940. {
  1941. Driver.finally_count++;
  1942. }
  1943. }
  1944. static void Main()
  1945. {
  1946. var t = F();
  1947. t.Wait();
  1948. Console.WriteLine(Driver.finally_count);
  1949. }
  1950. }";
  1951. var expected = @"
  1952. 1
  1953. ";
  1954. CompileAndVerify(source, expected);
  1955. }
  1956. [Fact]
  1957. public void Conformance_Awaiting_Methods_Parameter003()
  1958. {
  1959. var source = @"
  1960. using System;
  1961. using System.Threading.Tasks;
  1962. using System.Collections.Generic;
  1963. using System.Threading;
  1964. class TestCase
  1965. {
  1966. public static int Count = 0;
  1967. public static T Foo<T>(T t)
  1968. {
  1969. return t;
  1970. }
  1971. public async static Task<T> Bar<T>(T t)
  1972. {
  1973. await Task.Delay(1);
  1974. return t;
  1975. }
  1976. public static async void Run()
  1977. {
  1978. try

Large files files are truncated, but you can click here to view the full file