555 votes

Si mon interface doit renvoyer la tâche, quel est le meilleur moyen d’avoir une implémentation sans opération?

Dans le code ci-dessous, en raison de l'interface, la classe 'LazyBar' doit retourner une tâche à partir de la méthode (et pour l'amour du arguments ne peut pas être changé). Si 'LazyBar de la mise en œuvre est inhabituel en ce qu'il se passe à courir vite et de manière synchrone - quelle est la meilleure façon de retourner un Pas d'Opération de tâche à partir de la méthode?

Je suis allé à la Tâche.Delay(0) ci-dessous, cependant je voudrais savoir si cela a tout de la performance des effets secondaires, si la fonction est appelée un lot (pour l'amour du arguments, dire des centaines de fois par seconde):

  • Est-ce à sucre syntaxique de l'onu-le vent de quelque chose de grand?
  • Sera-t-elle un encrassement de mon application pool de threads?
  • Est le compilateur cleaver assez à faire avec du Retard(0)' différemment?
  • "De retour de Mission.Exécuter(() => { });' être différent?

Est-il un meilleur moyen?

Merci beaucoup,

Jon :-)

using System.Threading.Tasks;

namespace MyAsyncTest
{
    internal interface IFooFace
    {
        Task WillBeLongRunningAsyncInTheMajorityOfImplementations();
    }

    /// <summary>
    /// An implementation, that unlike most cases, will not have a long-running
    /// operation in 'WillBeLongRunningAsyncInTheMajorityOfImplementations'
    /// </summary>
    internal class LazyBar : IFooFace
    {
        #region IFooFace Members

        public Task WillBeLongRunningAsyncInTheMajorityOfImplementations()
        {
            // First, do something really quick
            var x = 1;

            // Can't return 'null' here! Does 'Task.Delay(0)' have any performance considerations?
            // Is it a real no-op, or if I call this a lot, will it adversely affect the
            // underlying thread-pool? Better way?
            return Task.Delay(0);

            // Any different?
            // return Task.Run(() => { });

            // If my task returned something, I would do:
            // return Task.FromResult<int>(12345);
        }

        #endregion
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            Test();
        }

        private static async void Test()
        {
            IFooFace foo = FactoryCreate();
            await foo.WillBeLongRunningAsyncInTheMajorityOfImplementations();
            return;
        }

        private static IFooFace FactoryCreate()
        {
            return new LazyBar();
        }
    }
}

785voto

Reed Copsey Points 315315

L'utilisation de Task.FromResult(0) ou Task.FromResult<object>(null) entraînera moins de frais généraux que la création d'un Task avec une expression sans opération. Lors de la création d'un Task avec un résultat prédéterminé, aucune surcharge de planification n'est impliquée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X