当前位置: 首页 > 知识库问答 >
问题:

不可等待,如“火灾”

澹台阳秋
2023-03-14

想改进这个问题吗 通过编辑这篇文章,更新问题,以便用事实和引文来回答。

我们需要在代码中编写一些日志
日志是通过网络请求写入的,该请求会记录一些信息(记录器是Http API模块),但如果API中出现异常,我们不想中断整个流程。

我不想使用任务。运行这种操作,因为它不好。

但是后来我想到了非等待内联函数,类似于这样:

private static readonly HttpClient client = new HttpClient();

void Main()
{

    Console.WriteLine(1);
    async Task LogMe()
    {
        var response = await client.PostAsync("http://www.NOTEXISTS.com/recepticle.aspx", null);
        var responseString = await response.Content.ReadAsStringAsync();
        //response.EnsureSuccessStatusCode(); // I don't need this here
        Console.WriteLine("error");
    }

    //some code
    LogMe();
    //some code
    Console.WriteLine(3);

}

输出:

1
2

问题:

这是一个可行的解决方案,以“火灾和忘记”模式登录
如果我在这个内联方法中创建对象,那么什么时候对它们进行GC'ed呢?


共有2个答案

麹飞航
2023-03-14
匿名用户

我不想使用任务。运行这种操作,因为它很糟糕。

一点也不坏。这只是你工具带上的另一个工具。

理解异步方法的工作原理很重要。异步方法都开始同步运行,就像其他方法一样。魔法发生在第一次等待一个未完成的任务时。此时,await会看到未完成的任务,然后方法返回。通常,它会返回自己未完成的任务,除非该方法是异步void,否则它不会返回任何内容。

异步不是关于方法如何运行。它是关于方法如何等待。

因此,在您的代码中,LogMe()将开始在同一线程上运行。只有当您等待响应时,Task才会在调用堆栈上返回,您可以自由等待或不等待。

设置请求并发送请求所需的时间并不多。所以你不会注意到。但是,如果您在请求之前做了一些CPU密集型工作,那么使用任务是合适的。运行,因为这会告诉它从另一个线程开始,所以它不会阻碍您。

如果这是ASP。NET(而非Core),则您可以从使用任务中获益。运行,或使用。ConfigureAwait(false),因为否则它将尝试返回相同的同步上下文(当前传入HTTP请求的上下文),这意味着当前请求无法在日志()完成之前完成。

然而,如果你打算开火并忘记,那么请记住,无论是什么原因启动了操作,都不知道它是否成功。如果您想在其他地方(文本文件或其他东西)记录故障,应该在日志中使用try(尝试)catch(捕获)<如果发送请求时出现问题(DNS查找失败、无响应等),code>PostAsync将引发html" target="_blank">异常。

艾令秋
2023-03-14

我不想使用任务。运行这种操作,因为它很糟糕。

识别/指定此类语句的上下文非常重要<代码>任务。ASP上的运行不正确。净额。在客户端的GUI应用程序中使用它完全可以。

我们需要在代码中编写一些日志。

我强烈建议使用已建立的日志库。其中大多数都是通过使用内存中的队列来工作的,该队列由代码(同步)写入,并由后台线程持续处理。这是一种已经确立的模式。

这是一个可行的解决方案,以“火灾和忘记”模式登录?

“触发并忘记”的问题之一是您不知道何时有错误。已建立的日志库都有某种系统来处理与日志后端通信的错误;您发布的代码只会忽略它们。

如果我在这个内联方法中创建对象,它们什么时候会被GC'ed呢?

从概念上讲,只要异步方法将来继续执行,它们就充当GC“根”。因此,当方法完成时,本地对象将被GC'ed。

 类似资料:
  • 我有一个动态加载的页面,其中包含一个按钮。我正在尝试等待selenium使用C#绑定点击按钮。我有以下代码: 不过这不管用。click事件永远不会被触发。selenium脚本不会抛出异常警告ID为“addInspectionButton”的元素不存在。它只是不能点击它。如果我加一根线。Sleep(3000)在wait语句和我获得按钮元素句柄的那一行之间。 我没有使用预期条件.元素在这里正确点击吗?

  • 我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似

  • 当我点击一个按钮时,它会显示一个带有另一个按钮的表单,我想点击其中一个。这是一个视频(非常短),请观看http://screencast.com/t/zyliSemW1s1 所以我点击“买票”按钮,简单如下: 然后我等待下一个按钮被点击。 我使用下一个代码: 之后,我点击我等待的按钮: 我得到错误:元素在这一点上是不可点击的。 据我所知,该方法预期的条件。ElementToBeClickable(

  • 任务或任务 我们也可以定义自己的可实现对象。对象应具有以下资格。 < li >它有一个GetAwaiter()方法(实例方法或扩展方法); < li >其GetAwaiter()方法返回一个Awaiter。在下列情况下,对象是一个标识符: < ul > < li >它实现INotifyCompletion或ICriticalNotifyCompletion接口; < li >它有一个IsCompl

  • 问题内容: 我正在尝试使用中央集中调度来等待文件完成下载再继续。这个问题是从以下问题衍生出来的:Swift(iOS),等待所有图像下载完成后再返回。 我只是在尝试找出如何使dispatch_group_wait(或类似的方法)真正等待,而不仅仅是在下载完成之前继续。请注意,如果我使用NSThread.sleepForTimeInterval而不是调用downloadImage,它会等待就好。 我想

  • 问题内容: 我有一个基于GWT的页面,我想使用HtmlUnit为它创建一个HTML快照。该页面使用产品上的Ajax / JavaScript信息进行加载,因此大约1秒钟会出现一条正在加载…消息,然后显示内容。 问题是HtmlUnit似乎无法捕获信息,而我得到的只是“正在加载…”范围。 以下是HtmlUnit的实验代码,我在其中尝试给它足够的时间来等待数据加载,但是它似乎并没有改变任何内容,而且我仍