在 c# 4.0 中执行即发即弃方法的最简单方法 [英] Simplest way to do a fire and forget method in c# 4.0

查看:131
本文介绍了在 c# 4.0 中执行即发即弃方法的最简单方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的很喜欢这个问题:

I really like this question:

最简单的点火方法在 C# 中忘记方法?

我只想知道,既然我们在 C# 4.0 中有了 Parallel 扩展,是否有更好的更简洁的方式来实现 Fire &忘记并行 linq?

I just want to know that now that we have Parallel extensions in C# 4.0 is there a better cleaner way to do Fire & Forget with Parallel linq?

推荐答案

不是 4.0 的答案,但值得注意的是,在 .Net 4.5 中,您可以通过以下方式更简单:

Not an answer for 4.0, but worth noting that in .Net 4.5 you can make this even simpler with:

#pragma warning disable 4014
Task.Run(() =>
{
    MyFireAndForgetMethod();
}).ConfigureAwait(false);
#pragma warning restore 4014

pragma 是禁用警告,告诉您将此任务运行为 fire and forget.

The pragma is to disable the warning that tells you you're running this Task as fire and forget.

如果大括号内的方法返回一个任务:

If the method inside the curly braces returns a Task:

#pragma warning disable 4014
Task.Run(async () =>
{
    await MyFireAndForgetMethod();
}).ConfigureAwait(false);
#pragma warning restore 4014

让我们分解一下:

Task.Run 返回一个 Task,它会生成一个编译器警告(警告 CS4014),指出此代码将在后台运行 - 这正是您想要的,因此我们禁用了警告 4014.

Task.Run returns a Task, which generates a compiler warning (warning CS4014) noting that this code will be run in the background - that's exactly what you wanted, so we disable warning 4014.

默认情况下,Tasks 会尝试Marshal back to the original Thread",这意味着该 Task 将在后台运行,然后尝试返回到启动它的 Thread.通常在原始线程完成后触发并忘记任务完成.这将导致抛出 ThreadAbortException.在大多数情况下,这是无害的——它只是告诉你,我试图重新加入,我失败了,但无论如何你都不在乎.但是,在您的生产日志或本地开发人员的调试器中使用 ThreadAbortExceptions 仍然有点嘈杂..ConfigureAwait(false) 只是一种保持整洁的方式,并明确地说,在后台运行它,就是这样.

By default, Tasks attempt to "Marshal back onto the original Thread," which means that this Task will run in the background, then attempt to return to the Thread that started it. Often fire and forget Tasks finish after the original Thread is done. That will cause a ThreadAbortException to be thrown. In most cases this is harmless - it's just telling you, I tried to rejoin, I failed, but you don't care anyway. But it's still a bit noisy to have ThreadAbortExceptions either in your logs in Production, or in your debugger in local dev. .ConfigureAwait(false) is just a way of staying tidy and explicitly say, run this in the background, and that's it.

由于这很罗嗦,尤其是丑陋的 pragma,我为此使用了一个库方法:

Since this is wordy, especially the ugly pragma, I use a library method for this:

public static class TaskHelper
{
    /// <summary>
    /// Runs a TPL Task fire-and-forget style, the right way - in the
    /// background, separate from the current thread, with no risk
    /// of it trying to rejoin the current thread.
    /// </summary>
    public static void RunBg(Func<Task> fn)
    {
        Task.Run(fn).ConfigureAwait(false);
    }

    /// <summary>
    /// Runs a task fire-and-forget style and notifies the TPL that this
    /// will not need a Thread to resume on for a long time, or that there
    /// are multiple gaps in thread use that may be long.
    /// Use for example when talking to a slow webservice.
    /// </summary>
    public static void RunBgLong(Func<Task> fn)
    {
        Task.Factory.StartNew(fn, TaskCreationOptions.LongRunning)
            .ConfigureAwait(false);
    }
}

用法:

TaskHelper.RunBg(async () =>
{
    await doSomethingAsync();
}

这篇关于在 c# 4.0 中执行即发即弃方法的最简单方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆