【发布时间】:2013-01-17 04:05:49
【问题描述】:
使用命令模式返回仅休眠 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;
}
【问题讨论】:
-
您应该在此处发布相关代码。如果您在这里发布太多内容,那么您应该简化示例。
-
我相信幕后有一个工作项调度程序,它具有启发式方法来确定何时并行运行任务、创建新线程、结束现有线程等。如果您创建 1,000,000 个任务它不会立即创建那么多线程,它会弄清楚如何最好地执行它们,因为那么多线程会杀死 CPU。一个需要 5 秒才能完成的任务可能不是这个启发式的最佳选择。请参阅stackoverflow.com/questions/3105988/… 了解更多信息。
-
1) 您甚至还没有提供所有代码。您尚未提供
CommandExecutor或MoreFakes的定义。我们应该能够复制粘贴这样的示例并运行它。 2) 你这里有太多不需要的代码。其中绝大多数实际上并不重要。使用Task对象的要点是您不需要这些类型的抽象。 -
@ta.speot.is 这不是这里的问题。他的编码方式使得它们根本不可能并行化。
-
@Servy 为你点赞。