Come posso assegnare un nome a un'attività in TPL

Come posso assegnare un nome a un'attività in TPL

Potresti mettere in relazione qualsiasi oggetto con qualsiasi oggetto. Ecco un'estensione per Task. Utilizza un WeakReference in modo che l'attività possa ancora essere raccolta quando tutti i riferimenti non rientrano nell'ambito.

Utilizzo:

var myTask = new Task(...
myTask.Tag("The name here");
var nameOfTask = (string)myTask.Tag();

Classe di estensione:

public static class TaskExtensions
{
    private static readonly Dictionary<WeakReference<Task>, object> TaskNames = new Dictionary<WeakReference<Task>, object>(); 

    public static void Tag(this Task pTask, object pTag)
    {
        if (pTask == null) return;
        var weakReference = ContainsTask(pTask);
        if (weakReference == null)
        {
            weakReference = new WeakReference<Task>(pTask);
        }
        TaskNames[weakReference] = pTag;
    }

    public static object Tag(this Task pTask)
    {
        var weakReference = ContainsTask(pTask);
        if (weakReference == null) return null;
        return TaskNames[weakReference];
    }

    private static WeakReference<Task> ContainsTask(Task pTask)
    {
        foreach (var kvp in TaskNames.ToList())
        {
            var weakReference = kvp.Key;

            Task taskFromReference;
            if (!weakReference.TryGetTarget(out taskFromReference))
            {
                TaskNames.Remove(weakReference); //Keep the dictionary clean.
                continue;
            }

            if (pTask == taskFromReference)
            {
                return weakReference;
            }
        }
        return null;
    }
}

Non puoi davvero nominare un Task , ma puoi nominare il metodo che viene eseguito da un Task , che viene quindi mostrato nelle finestre Attività parallele. Quindi, se si nomina il Task s è importante per te, non usare lambda, usa i normali metodi con nome.

Sorprendentemente, funziona anche con Parallel , anche se c'è il Task non sta eseguendo direttamente il tuo metodo. Penso che ciò sia dovuto al fatto che Parallel Tasks in qualche modo conosce Task s da Parallel e li gestisce in modo diverso.


Non puoi nominare le attività.

La libreria delle attività utilizza internamente un pool di thread, quindi i thread non possono essere denominati. Inoltre, il tuo approccio all'ereditarietà non funzionerà, perché metodi come ".ContinueWith()" creeranno sempre una nuova attività, che non erediterà dalla tua classe.