简体   繁体   English

C# Singleton - 使用异步等待触发并忘记

[英]C# Singleton - Fire and forget with Async await

Context - I am using Azure CosmosDB GraphAPI - and azure doesn't have logging for it, Sad!上下文 - 我正在使用 Azure CosmosDB GraphAPI - 而 azure 没有日志记录,可悲! So we came up with using our own logging of queries and its metaproperties所以我们想出了使用我们自己的查询记录及其元属性

I implemented a Singleton class that is used by other services for DB Calls and I want to have a fire and forget the call to the logger.我实现了一个 Singleton class 被其他服务用于 DB 调用,我想着火并忘记对记录器的调用。

    public class GraphDatabaseQuery : IGraphDatabaseQuery
    {
        private readonly GremlinClient gremlinClient;
        public GraphDatabaseQuery()
        {
            if (gremlinClient == null)
            {
                gremlinClient = CosmosDbClient.Instance;
            }
            else
            {
                if (gremlinClient.NrConnections == 0)
                {
                    gremlinClient = CosmosDbClient.Instance;
                }
            }
        }

        public async Task<ResultSet<dynamic>> SubmitQueryAsync(string query, string fullName)
        {
            var response = await gremlinClient.SubmitAsync<dynamic>(query);
            _ = SendQueryAnalytics(response, query, fullName);
            return response;
        }
        public async Task<dynamic> SubmitQueryWithSingleSingleResultAsync(string query, string fullName)
        {
            var response = await gremlinClient.SubmitWithSingleResultAsync<dynamic>(query);
            return response;

        }

        private async Task<bool> SendQueryAnalytics(ResultSet<dynamic> response, string query, string fullName)
        {
            try
            {
                await new QueryAnalytics().pushData(response, query, fullName); // breakpoint here 
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return true;
        }
    }

in startup.cs在启动.cs

            services.AddSingleton<IGraphDatabaseQuery, GraphDatabaseQuery>();

and the interface和界面

    public interface IGraphDatabaseQuery
    {
        public Task<ResultSet<dynamic>> SubmitQueryAsync(string query, string fullName);
        public Task<dynamic> SubmitQueryWithSingleSingleResultAsync(string query, string fullName);

    }

Whenever I test it the breakpoint hits "SendQueryAnalytics" but i assume at that moment the response from the calling function would be sent back每当我测试它时,断点就会命中“SendQueryAnalytics”,但我假设那时来自调用 function 的响应将被发回

is this not working because I am using the singleton pattern?这是因为我使用的是 singleton 模式而不起作用吗?

Whenever I test it the breakpoint hits "SendQueryAnalytics" but i assume at that moment the response from the calling function would be sent back每当我测试它时,断点就会命中“SendQueryAnalytics”,但我假设那时来自调用 function 的响应将被发回

No. All asynchronous methods begin executing synchronously .不,所有异步方法都开始同步执行

So what happens is that SendQueryAnalytics is called and begins executing, enters the try block, creates a new QueryAnalytics instance, and calls pushData .所以发生的事情是SendQueryAnalytics被调用并开始执行,进入try块,创建一个新的QueryAnalytics实例,并调用pushData pushData also begins executing and (presumably) returns an incomplete Task . pushData也开始执行并且(可能)返回一个不完整的Task Then the await in SendQueryAnalytics observes that that Task is incomplete and returns an incomplete Task to SubmitQueryAsync , which discards that Task instance and then returns the response.然后SendQueryAnalytics中的await观察到该Task不完整,并向 SubmitQueryAsync 返回一个不完整的TaskSubmitQueryAsync丢弃该Task实例,然后返回响应。

Thus, seeing the response returned after that breakpoint is normal.因此,在该断点之后看到返回的响应是正常的。

I don't think that the singleton pattern has something to do with it.我不认为 singleton 模式与它有关。 Since you want a 'fire and forget' why don't you use something like hangfire ?既然您想要“一劳永逸”,为什么不使用类似hangfire的东西?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM