是什么阻止了TPL旋转另一个线程

本文关键字:旋转 另一个 线程 TPL 是什么 | 更新日期: 2023-09-27 17:53:38

使用命令模式返回仅休眠5秒的任务,3个任务完成的总时间约为15秒。

我在做什么,使这段代码从"并行"执行?

主叫码

        var timer = new Stopwatch();
        timer.Start();
        var task = CommandExecutor.ExecuteCommand(new Fake());
        var task2 = CommandExecutor.ExecuteCommand(new Fake());
        var task3 = CommandExecutor.ExecuteCommand(new Fake());
        Task.WaitAll(new Task[]
        {
            task, task2, task3
        });
        timer.Stop();
        Debug.Print("{0}ms for {1},{2},{3} records", timer.ElapsedMilliseconds, task.Result.Count, task2.Result.Count(), task3.Result.Count());

正在执行的命令

public class Fake : Command<Task<Dictionary<string, string[]>>>
{
    public override string ToString()
    {
        return string.Format("Fake");
    }
    protected override void Execute()
    {
        new System.Threading.ManualResetEvent(false).WaitOne(5000);
        Result = Task.Factory.StartNew(() => new Dictionary<string, string[]>());
    }
}

命令抽象

public abstract class Command
{
    public void Run()
    {
        try
        {
            var timer = new Stopwatch();
            timer.Start();
            //Debug.Print("{0}-{1}", ToString(), "Executing");
            Execute();
            timer.Stop();
            Debug.Print("{0}-{1} Duration: {2}ms", ToString(), "Done", timer.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture));             
        }
        catch (Exception ex)
        {
            Debug.Print("Error processing task:" + ToString(), ex);
        }
    }
    public abstract override string ToString();
    protected abstract void Execute();
}
/// <summary>
/// A command with a return value
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Command<T> : Command
{
    public T Result { get; protected set; }
    public T GetResult()
    {
        Run();
        return Result;
    }
}

命令执行器

public class CommandExecutor
{
    /// <summary>
    ///     Executes the command.
    /// </summary>
    /// <param name="cmd">The CMD.</param>
    public static void ExecuteCommand(Command cmd)
    {
        cmd.Run();
    }
    /// <summary>
    ///     Executes the command for commands with a result.
    /// </summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    /// <param name="cmd">The CMD.</param>
    /// <returns></returns>
    public static TResult ExecuteCommand<TResult>(Command<TResult> cmd)
    {
        ExecuteCommand((Command) cmd);
        return cmd.Result;
    }

是什么阻止了TPL旋转另一个线程

问题是,您不是在实际的Task对象中等待,而是在创建任务的方法中等待,然后才实际提供该任务:

protected override void Execute()
{
    new System.Threading.ManualResetEvent(false).WaitOne(5000);
    Result = Task.Factory.StartNew(() => new Dictionary<string, string[]>());
}

应该改成:

protected override void Execute()
{
    Result = Task.Factory.StartNew(() =>
    {
        new System.Threading.ManualResetEvent(false).WaitOne(5000);
        return new Dictionary<string, string[]>();
    });
}