【发布时间】:2017-03-23 11:58:09
【问题描述】:
我的网站仅在应用程序需要时才需要初始化一些数据,并且只能执行一次。初始化必须调用 API 来获取数据。
所以基本上,我想我需要制作一个 lazy singleton,它会在第一次访问时调用 api。但是当我使用 HttpClient 类中的异步方法 GetAsync 时遇到了问题。调用 API 时发生了崩溃,但我的 TryCatch 没有捕获到异常。
我尝试将Piv GetPiv() 转换为Task<Piv> GetPiv(),但我不知道如何将它与 Lazy 对象一起使用。
public class PivHelper
{
private static readonly Lazy<Piv> _lazyPiv = new Lazy<Piv>(GetPiv);
public string Header()
{
return _lazyPiv.Value.Header;
}
public string Footer()
{
return _lazyPiv.Value.Footer;
}
public string Scripts()
{
return _lazyPiv.Value.Scripts;
}
public string Styles()
{
return _lazyPiv.Value.Styles;
}
private static Piv GetPiv()
{
try
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("http://some-web-site.com").Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<Piv>().Result;
}
else
{
return new Piv();
}
}
catch (Exception ex)
{
return new Piv();
}
}
}
public class Piv
{
public string Header { get; set; }
public string Footer { get; set; }
public string Styles { get; set; }
public string Scripts { get; set; }
}
public static class MtoHelper
{
private static readonly Lazy<PivHelper> lazyPivHelper = new Lazy<PivHelper>(() => new PivHelper());
public static PivHelper Piv
{
get
{
return lazyPivHelper.Value;
}
}
}
我的 _Layout.cshtml 文件
<!DOCTYPE html>
<html>
<head>
<!-- Instead of using our own copy of the piv.css, we use the one
coming from the webservices -->
<!--<link href="~/content/piv.css" rel="stylesheet" type="text/css">-->
@MtoHelper.Piv.Styles()
<link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>
<header id="pageHeaderContainer" class="container">
@MtoHelper.Piv.Header()
</header>
<section id="main" class="container">
@RenderBody()
</section>
<footer id="pageFooterContainer" class="container">
@MtoHelper.Piv.Footer()
</footer>
@MtoHelper.Piv.Scripts()
</body>
</html>
【问题讨论】:
-
调用
.Result通常是个坏主意。你可以让GetPiv()异步吗?public static async Task<Piv> GetPiv()?然后你可以await其中调用的异步操作。 -
这是我试图做的,但是,如果 GetPiv 是一个任务
,我如何使用 Lazy 对象。这就是我卡住的地方。 -
公平的问题。这看起来很有帮助:blogs.msdn.microsoft.com/pfxteam/2011/01/15/asynclazyt
标签: c# async-await singleton lazy-initialization