51 votes

Comment créer une méthode asynchrone

J'ai une méthode simple dans mon application en C#, il sélectionne le fichier à partir du serveur FTP et l'analyse et stocke les données dans la DB. Je veux qu'il soit asynchrone, de sorte que l'utilisateur d'effectuer d'autres opérations sur l'App, une fois que l'analyse est fait, il doit obtenir le message suivant: "l'Analyse est faite".

Je sais que cela peut être réalisé par le biais de méthode asynchrone appeler, mais je ne sais pas comment faire, quelqu'un peut-il m'aider svp??

74voto

Callum Rogers Points 6769

Vous avez besoin d'utiliser des délégués et de l' BeginInvoke méthode qu'ils contiennent pour exécuter une autre méthode asynchrone. A la fin de la méthode en cours d'exécution par le délégué, vous pouvez informer l'utilisateur. Par exemple:

class MyClass
{
    private delegate void SomeFunctionDelegate(int param1, bool param2);
    private SomeFunctionDelegate sfd;

    public MyClass()
    {
        sfd = new SomeFunctionDelegate(this.SomeFunction);
    }

    private void SomeFunction(int param1, bool param2)
    {
        // Do stuff

        // Notify user
    }

    public void GetData()
    {
        // Do stuff

        sfd.BeginInvoke(34, true, null, null);
    }
}

Lire jusqu'à http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx

20voto

Zain Ali Points 3813

essayez cette méthode

public static void RunAsynchronously(Action method, Action callback) {
    ThreadPool.QueueUserWorkItem(_ =>
    {
        try {
            method();
        } 
        catch (ThreadAbortException) { /* dont report on this */ } 
        catch (Exception ex) {
        }
        // note: this will not be called if the thread is aborted
        if (callback!= null) callback();
    });
}

Utilisation:

RunAsynchronously( () => { picks file from FTP server and parses it}, 
       () => { Console.WriteLine("Parsing is done"); } );

6voto

John Saunders Points 118808

De tout temps, vous êtes en train de faire quelque chose asynchrone, vous êtes à l'aide d'un thread séparé, soit un nouveau fil de discussion, ou d'une prise à partir du pool de threads. Cela signifie que ce que vous faites de manière asynchrone doit être très prudent sur les interactions avec les autres threads.

Une façon de le faire est de placer le code de l'async fil (appelons-le fil "A") avec l'ensemble de ses données dans une autre classe (appelons-la classe "A"). Assurez-vous que le fil "A" seulement accède à des données dans la classe "A". Si le fil "A", qui touche de classe "A", et aucun autre thread touche de classe "A"'s de données, puis il y a un problème de moins:

public class MainClass
{
    private sealed class AsyncClass
    {
        private int _counter;
        private readonly int _maxCount;

        public AsyncClass(int maxCount) { _maxCount = maxCount; }

        public void Run()
        {
            while (_counter++ < _maxCount) { Thread.Sleep(1); }
            CompletionTime = DateTime.Now;
        }

        public DateTime CompletionTime { get; private set; }
    }

    private AsyncClass _asyncInstance;
    public void StartAsync()
    {
        var asyncDoneTime = DateTime.MinValue;
        _asyncInstance = new AsyncClass(10);
        Action asyncAction = _asyncInstance.Run;
        asyncAction.BeginInvoke(
            ar =>
                {
                    asyncAction.EndInvoke(ar);
                    asyncDoneTime = _asyncInstance.CompletionTime;
                }, null);
        Console.WriteLine("Async task ended at {0}", asyncDoneTime);
    }
}

Notez que la seule partie de l' AsyncClass qui est abordée à partir de l'extérieur, c'est son interface publique, et la seule partie de ce qui est des données est - CompletionTime. Notez que c'est seulement touché après la tâche asynchrone est terminée. Cela signifie que rien ne peut interférer avec les tâches de fonctionnement interne, et il ne peut pas interférer avec quoi que ce soit d'autre.

4voto

tanascius Points 22712

Voici deux liens sur le filetage en C#

J'avais commencer à lire à propos de la classe BackgroundWorker

4voto

Fischer Points 121

Dans Asp.Net j'utilise beaucoup de statique des méthodes pour les travaux à faire. Si il s'agit tout simplement d'un travail où je dois pas de réponse ou de qualité, je fais quelque chose de simple comme ci-dessous. Comme vous pouvez le voir, j'ai le choix de demander soit l'ResizeImages ou ResizeImagesAsync selon si je veux attendre qu'il ait fini ou pas

Explication du Code: - je utiliser http://imageresizing.net/ pour recadrer/redimensionner les images et la méthode SaveBlobPng est de stocker les images d'Azur (cloud), mais comme cela n'est pas pertinent pour cette démonstration, je ne comprend pas ce code. Ses un bon exemple de tâches consommatrices de temps si

private delegate void ResizeImagesDelegate(string tempuri, Dictionary<string, string> versions);
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
    ResizeImagesDelegate worker = new ResizeImagesDelegate(ResizeImages);
    worker.BeginInvoke(tempuri, versions, deletetemp, null, null);
}
private static void ResizeImages(string tempuri, Dictionary<string, string> versions)
{
    //the job, whatever it might be
    foreach (var item in versions)
    {
        var image = ImageBuilder.Current.Build(tempuri, new ResizeSettings(item.Value));
        SaveBlobPng(image, item.Key);
        image.Dispose();
    }
}

Ou aller pour le filetage de sorte que vous n'avez pas à s'embêter avec les Délégués

private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
    Thread t = new Thread (() => ResizeImages(tempuri, versions, null, null));
    t.Start(); 
}

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