【发布时间】:2017-11-13 23:00:51
【问题描述】:
我已经读过以这种方式执行虚假异步方法是一个坏主意:
public int myMethodSyn()
{
//sync operations
return result;
}
public async int myMethodAsync()
{
return await Task.Run(myMethodSync);
}
我读到它的原因之一是,例如,ASP 可能会遇到此类库的可伸缩性问题,因为任务使用线程池,而 ASP 需要线程池来处理每个调用。所以库可以消耗线程池al block ASP的所有线程。所以最好让客户端决定如何使用线程池。
如果没有错,Parallel.Invoke 也使用线程池来并行运行方法,所以我想如果我在我的库中使用使用 parallel.Invoke 或 parallel.Foreach 或任何这种方式的方法并行运行代码,我会遇到同样的问题。是真的吗?
我的想法是并行运行两个方法,因为它们是独立的,如果我并行运行它们可以获得更好的性能。所以我会有类似的东西:
public int myMainMethodSync()
{
int result01 = myMethod01Sync();
int result02 = myMethod02Sync();
return result01 + result02;
}
private void myMethod01Sync()
{
}
private void myMethod02Sync()
{
}
public int myMainMethodAsync()
{
Task myTsk01 = Task.Run(myMethod01Sync);
Task myTsk02 = Task.Run(myMethod02Sync);
Task.WhenAll(myTsk01, myTsk02);
return myTsk01.Result + myTsk02.Result;
}
public int Task myMainMethodParallel()
{
int result01;
int result02;
Parallel.Invoke(() => result01 = myMethod01Sync(),
() => result02 = myMethod02Sync());
return result01 + result02;
}
这个想法是有一个同步方法来同步运行这两种方法。所以使用该库的客户端知道该方法不会使用线程池。
稍后我有两个选项可以同时运行这些方法,使用任务或使用 parallel.Invoke。
在任务的情况下,我使用了假异步方法,因为我将同步方法包装在一个任务中,该任务使用线程池中的两个线程。如果我没记错的话,不建议这样做。
另一个选项是使用Parallel.Invoke,它也使用线程池中的线程,所以我猜它和任务有同样的问题,所以我想也不推荐它。
在我的情况下,我更喜欢使用任务,因为我可以根据一些条件来决定何时运行 method02Sync 的条件,因此如果我可以节省分配线程来运行第二种方法的成本知道在某些情况下不需要它。我猜是并行的。调用这是不可能的。
但是,我认为在这种情况下,我也是如何实现同步方法的,我让客户端选择它认为更好的方法,所以在异步方法中使用任务确实是一个不好的选择?
如果两个解决方案都不好,tasks 和 Parallel.Invloke,那么不建议在库中运行并行代码并且只在库的 UI 或客户端中使用它?因为我猜在这种情况下并行的使用非常有限,因为在顶层,在 UI 中,如果它决定可以使用并行是不可能的,因为告诉库是否使用线程,因为它不会'没有并行方法。
总之,我的解决方案,公开同步和异步方法是个坏主意吗?在库中使用任务或并行代码是个坏主意吗?如果其中一个是更好的选择,哪个更好?
谢谢。
【问题讨论】:
-
您调用的每个方法通常需要多长时间?并行运行它们能给你带来多大的加速?
-
我的问题更多是关于尝试了解任务和 Parallel.Invoke 之间的区别以及开发使用并行的库的最佳方法,如果开发使用并行的库是一个好主意。
标签: c# parallel-processing task-parallel-library