Mat*_*ves 16 .net azure azure-functions
我创建了一些非常简单的Azure功能.他们从Couchbase(在VM上运行Azure)中读取和写入数据.
我担心我在Azure功能中与Couchbase建立的连接.我Cluster每次都创建一个对象.这是一项昂贵的操作,我通常只会在普通的网络应用程序中执行一次.但是在Azure功能中,我new每次都在努力.
除了Couchbase之外,实例化这样的对象还有很多代价.有没有办法创建一个单例,或Azure函数可以在调用之间重用的某种共享对象?
Ste*_*ary 19
在Azure Functions上处理单例时,有几个注意事项.一个是全球状态的 AF调用共享.因此,如果一个函数被调用一次然后再调用(很快主机没有卸载你的代码),那么初始化只发生一次.另一个考虑因素是AF可以完全自由地同时启动多个AF调用 - 因此任何单例都需要线程安全(包括初始化).
这意味着你将要使用Lazy<T>/ AsyncLazy<T>.但是,请记住,AF(使用这些类型)将保留下次调用的单例状态(初始化后),即使它失败也是如此.这可能是云计算的一个问题,因为如果AF启动时出现网络(或配置)错误,您希望在下一次AF调用时重试初始化.
总之,您希望以一种线程安全的方式使用Lazy<T>/ 并且不会保留故障.AsyncLazy<T>
有了Lazy<T>,这意味着你必须使用LazyThreadSafetyMode.PublicationOnly标志 并将一个函数传递给构造函数(不只是隐式使用默认构造函数T).请注意,这意味着您需要确保初始化函数本身是线程安全的,因为它可以由多个线程同时执行.
有了AsyncLazy<T>,你必须使用AsyncLazyFlags.RetryOnFailure旗帜.由于AsyncLazy<T>本质上是a Lazy<Task<T>>,异步初始化任务在所有同时调用者之间"共享",然后Lazy<Task<T>>如果失败则以原子方式替换为新实例.因此异步初始化函数不需要是线程安全的.
由于这一切都很好(特别是对于多个单身人士)是相当复制和粘贴的,所以我为我正在研究的AF项目抽象出来:
AsyncLazy<T>用于同步和异步单例,因此同步初始化函数将"共享"其工作,因此即使多个线程同时请求实例,它也只运行一次.这需要一段时间才能达到这一点,但我对它的结果非常满意.关于这个博客的意思也是......
Jes*_*ter 10
昂贵的连接对象的静态属性可以正常工作,但我建议将它们包装好,Lazy<>以便开箱即可保证线程安全.
基于示例博客文章,您链接到一个示例,使用可保证的线程安全方式使所有函数调用中的存储桶可重用,可能如下所示:
public class FunctionClass
{
private static Lazy<IBucket> LazyBucket = new Lazy<IBucket>(() =>
{
var uri = ConfigurationManager.AppSettings["couchbaseUri"];
var cluster = new Cluster(new ClientConfiguration
{
Servers = new List<Uri> { new Uri(uri) }
});
var bucketName = ConfigurationManager.AppSettings["couchbaseBucketName"];
var bucketPassword = ConfigurationManager.AppSettings["couchbaseBucketPassword"];
return cluster.OpenBucket(bucketName, bucketPassword);
});
// Your actual function implementation
public static async Task Run()
{
// Here you are guaranteed to get back a shared connection object to your bucket that has been
// initalized only once in a thread safe way
var initalizedOnceBucket = LazyBucket.Value;
// do something with the bucket
}
}
Run Code Online (Sandbox Code Playgroud)
如果应该共享的昂贵对象的构造依赖于某些异步调用(我怀疑Couchbase C#客户端可能具有异步版本的方法).您可以使用Stephen Cleary编写AsyncLazy<>的令人敬畏的Nito.AsyncEx Nuget包.Regular Lazy<>内置于.NET中,因此不需要任何外部依赖项.
您可以使用普通的单例,即返回某物单个实例的静态属性。与往常一样,请谨慎使用线程安全性,例如Lazy<T>按@Jesse的建议使用。
在执行对函数的第一次调用之前,您还可以使用静态构造函数进行初始化。根据定义,静态构造函数是线程安全的。
在这两种情况下,您都可以在同一实例(服务器)上运行的所有调用之间重用昂贵的东西。
| 归档时间: |
|
| 查看次数: |
3162 次 |
| 最近记录: |