Advertisement
eugene-gubenkov

Deadlock Task.Run

Sep 29th, 2017
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.92 KB | None | 0 0
  1. namespace DeadLockTest.Controllers
  2. {
  3.     using System;
  4.     using System.IO;
  5.     using System.Net.Http;
  6.     using System.Threading;
  7.     using System.Threading.Tasks;
  8.     using System.Web;
  9.     using System.Web.Http;
  10.  
  11.     namespace WebApplication1.Controllers
  12.     {
  13.         public class DefaultController : ApiController
  14.         {
  15.             private object _syncRoot = new object();
  16.  
  17.             [HttpGet]
  18.             [Route("test")]
  19.             public string Get()
  20.             {
  21.                 WriteInfo("\n***\nSTART");
  22.  
  23.                 //return BadAssAsync().Result; // deadlocks
  24.                 //return Wait(() => BadAssAsync()); // works!
  25.                 return Wait1(() => BadAssAsync()); // deadlocks sometimes
  26.                 //return Wait2(() => BadAssAsync()); // works!
  27.             }
  28.  
  29.             private async Task<string> BadAssAsync()
  30.             {
  31.                 HttpClient client = new HttpClient();
  32.  
  33.                 WriteInfo("BEFORE AWAIT");
  34.  
  35.                 var response = await client.GetAsync("http://google.com");
  36.  
  37.                 WriteInfo("AFTER AWAIT");
  38.  
  39.                 string content = await response.Content.ReadAsStringAsync();
  40.  
  41.                 WriteInfo("AFTER SECOND AWAIT");
  42.  
  43.                 return content;
  44.             }
  45.  
  46.             private T Wait<T>(Func<Task<T>> taskGen)
  47.             {
  48.                 var t = Task.Run(() =>
  49.                 {
  50.                     WriteInfo("RUN");
  51.  
  52.                     var task = taskGen();
  53.  
  54.                     return task.Result;
  55.                 });
  56.  
  57.                 WriteInfo("WAITING RESULT");
  58.  
  59.                 return t.Result;
  60.             }
  61.  
  62.             private T Wait1<T>(Func<Task<T>> taskGen)
  63.             {
  64.                 return Task.Run(() =>
  65.                 {
  66.                     WriteInfo("RUN");
  67.  
  68.                     var task = taskGen();
  69.  
  70.                     return task.Result;
  71.                 }).Result;
  72.             }
  73.  
  74.             private T Wait2<T>(Func<Task<T>> taskGen)
  75.             {
  76.                 return Task.Run(() =>
  77.                 {
  78.                     return taskGen();
  79.                 }).Result;
  80.             }
  81.  
  82.             private void WriteInfo(string checkpoint)
  83.             {
  84.                 string s = $"{checkpoint}: TID: {Thread.CurrentThread.ManagedThreadId}; SCTX: {SynchronizationContext.Current?.ToString() ?? "<null>"}; SCHEDULER: {TaskScheduler.Current}";
  85.  
  86.                 lock (_syncRoot)
  87.                     WriteF(s);
  88.             }
  89.  
  90.             private void WriteF(string s)
  91.             {
  92.                 string dir = HttpRuntime.AppDomainAppPath;
  93.                 string path = Path.Combine(dir, "log.txt");
  94.  
  95.                 using (var fs = new FileStream(path, FileMode.Append))
  96.                 using (var sw = new StreamWriter(fs))
  97.                 {
  98.                     sw.WriteLine(s);
  99.                     sw.Flush();
  100.                 }
  101.             }
  102.         }
  103.     }
  104.  
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement