GetJsonAsync(Uri uri)
{ using (var client = new HttpClient())
{ var jsonString = await client.GetStringAsync(uri); return JObject.Parse(jsonString);
}
}
// My "top-level" method.
public class MyController : ApiController
{ public string Get()
{ var jsonTask = GetJsonAsync(...); return jsonTask.Result.ToString();
}
}
```
#### 避免这种情况有三种最佳实践
1.在“库”异步方法中,尽可能使用ConfigureAwait(false)。
```
public static async Task GetJsonAsync(Uri uri)
{ using (var client = new HttpClient())
{ var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false); return JObject.Parse(jsonString);
}
}
```
2.不要阻止任务; 一直使用async。(即一用异步补补异步)
```
public async void Button1_Click(...)
{ var json = await GetJsonAsync(...);
textBox1.Text = json;
}
public class MyController : ApiController
{
public async Task Get()
{ var json = await GetJsonAsync(...); return json.ToString();
}
}
```
3.如果想结束async & await模式的调用,启动一个新的线程去await异步方法的返回结果
```
// My "library" method.public static async Task GetJsonAsync(Uri uri)
{ using (var client = new HttpClient())
{ var jsonString = await client.GetStringAsync(uri); return JObject.Parse(jsonString);
}
}
// My "top-level" method.
public string Get()
{ string jsonResultString = string.Empty;
Task.Run(async () =>
{
jsonResultString = await GetJsonAsync(...);
//await之后的代码
}).Wait();//此处启动线程是为了防止Async & Await模式造成死锁
return jsonResultString;
}
```
#### 2.经典线程锁(顺序问题)
```
int sharedResource1 = 1, sharedResource2 = 2;
var lockResource1 = newobject();
var lockResource2 = newobject();
var t1 = newThread(() =>{
Console.WriteLine("thead 1 begin");
lock (lockResource1)
{
Thread.Sleep(10);
lock (lockResource2)
{
sharedResource1++;
sharedResource2++;
}
}
Console.WriteLine("thead 1 end");
});
var t2 = newThread(() =>{
Console.WriteLine("thead 2 begin");
lock (lockResource2)
{
Thread.Sleep(10);
lock (lockResource1)
{
sharedResource1++;
sharedResource2++;
}
}
Console.WriteLine("thead 2 end");
});
t1.Start();
t2.Start();
```
#### 3.相互等待导致死锁
```
Task t1 = null, t2 = null;
t1 = Task.Factory.StartNew(() =>{
Console.WriteLine("task 1 begin");
Task.Delay(10);
Task.WaitAll(t2);
Console.WriteLine("task 1 end");
});
t2 = Task.Factory.StartNew(() =>{
Console.WriteLine("task 2 begin");
Task.Delay(10);
Task.WaitAll(t1);
Console.WriteLine("task 2 end");
});
Task.WaitAll(t1, t2);
Console.WriteLine("Done");
```
#### 4.WinForm Invoke抢夺UI线程死锁
```
privatevoid button1_Click(object sender, EventArgs e)
{ var t = Task.Factory.StartNew(() =>
{
Thread.Sleep(0); var text = Invoke(newFunc(() =>
{ // do some ui-dependent works
return Text;
})); return text + " - new title";
});
Text = t.Result;
}
```
#### 5.WPF Dispatcher切换死锁
```
privatevoid Button_Click(object sender, RoutedEventArgs e)
{ var t = Task.Factory.StartNew((state) =>
{
Task.Delay(10); var clr = (Color)newColorConverter()
.ConvertFromInvariantString(state asstring); var brush = Dispatcher.Invoke(() =>
{ // do some works
returnnewSolidColorBrush() { Color = clr };
}); return brush;
}, "red");
theButton.Background = t.Result;
}
```