Maison > développement back-end > C++ > Comment exécuter synchrone une méthode de tâche asynchrone en C #?

Comment exécuter synchrone une méthode de tâche asynchrone en C #?

DDD
Libérer: 2025-02-01 07:16:08
original
932 Les gens l'ont consulté

How to Synchronously Run an Async Task Method in C#?

Comment exécuter asynchrone dans la méthode C #

? Task<T>

Dans la programmation asynchrone, les méthodes sont généralement définies comme des tâches asynchrones (

) pour améliorer les performances et la capacité de réponse de l'application. Cependant, dans certains cas, vous devrez peut-être effectuer des méthodes asynchrones de manière synchrone pour déboguer ou tester. Task<T>

Plusieurs méthodes de gestion des méthodes asynchrones

Une méthode consiste à utiliser la méthode

, qui bloquera le thread d'appel jusqu'à la fin de la tâche. Cependant, dans certains cas, cela entraînera des problèmes de congélation et de performance de l'interface utilisateur. Task.Wait()

Un autre choix consiste à utiliser la méthode

. Bien qu'il semble d'exécuter la tâche simultanément, si la tâche n'est pas liée à la Commission, elle lancera en fait une exception. Task.RunSynchronously()

Enfin, vous pouvez utiliser une solution impliquant des cadres de programme de planification. Créez un nouveau , démarrez-le et attendez des tâches dans les expressions de lambda. Une fois la tâche terminée, définissez l'attribut

du programme de planification sur DispatcherFrame pour arrêter la pompe du programme de planification. Continue false Une solution fiable

Une solution plus forte consiste à utiliser un contexte synchrone, et le contexte pompera le message jusqu'à la fin de la tâche. Ceci est une classe qui implémente cette solution:

comment utiliser:
public static class AsyncHelpers
{
    /// <summary>
    /// 同步执行具有 void 返回值的异步 Task 方法。
    /// </summary>
    /// <param name="task">要执行的 Task 方法。</param>
    public static void RunSync(Func<Task> task)
    {
        var oldContext = SynchronizationContext.Current;
        var syncContext = new ExclusiveSynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(syncContext);

        syncContext.Post(async _ =>
        {
            try
            {
                await task();
            }
            catch (Exception e)
            {
                syncContext.InnerException = e;
                throw;
            }
            finally
            {
                syncContext.EndMessageLoop();
            }
        }, null);

        syncContext.BeginMessageLoop();

        SynchronizationContext.SetSynchronizationContext(oldContext);
    }

    /// <summary>
    /// 同步执行具有 T 返回类型的异步 Task<T> 方法。
    /// </summary>
    /// <typeparam name="T">返回类型</typeparam>
    /// <param name="task">要执行的 Task<T> 方法。</param>
    /// <returns>等待给定的 Task<T> 的结果。</returns>
    public static T RunSync<T>(Func<Task<T>> task)
    {
        var oldContext = SynchronizationContext.Current;
        var syncContext = new ExclusiveSynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(syncContext);
        T result;

        syncContext.Post(async _ =>
        {
            try
            {
                result = await task();
            }
            catch (Exception e)
            {
                syncContext.InnerException = e;
                throw;
            }
            finally
            {
                syncContext.EndMessageLoop();
            }
        }, null);

        syncContext.BeginMessageLoop();

        SynchronizationContext.SetSynchronizationContext(oldContext);

        return result;
    }

    private class ExclusiveSynchronizationContext : SynchronizationContext
    {
        // ... 为简洁起见省略了实现细节
    }
}
Copier après la connexion

Cette solution fonctionne bien sous la condition que la méthode asynchrone est nécessaire pour exécuter asynchrone.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal