有没有人知道它对ExecutionContext.Capture()和ExecutionContext.Run(context, work, state)是否昂贵?
它是否会降低性能,因此建议谨慎使用?
我之所以这样问,是因为我有一个ContextItem,在这里我保存上下文工作并在其中进行状态,以便稍后执行。因为我希望能够对在执行工作时可能抛出的异常作出反应,所以如果在工作中抛出异常,就会执行回退。我还有最后的工作,在任何情况下,如果抛出或不抛出异常,都会不加考虑地执行。由于我只能使用ExecutionContext一次,所以我必须对其中一个ContextItems进行三次ExecutionContext.Capture() .
还是这听起来是完全错误的做法?
发布于 2016-01-09 09:18:05
正如@Alois推荐的那样,我使用以下代码运行了一项测试,将锁定与捕获和排列的扩展进行比较:
class Program
{
private static readonly object _lock = new object();
private static readonly int numberOfItems = 1000000;
private static readonly int _numberOfIterations = 1000000;
private static void Main(string[] args)
{
MeasureTimeWithLocking();
MeasureTimeWithCapuringContext();
Console.WriteLine();
MeasureTimeWithLocking();
MeasureTimeWithCapuringContext();
Console.WriteLine();
MeasureTimeWithLocking();
MeasureTimeWithCapuringContext();
Console.ReadKey();
}
private static void MeasureTimeWithLocking()
{
List<ContextItem> items = new List<ContextItem>();
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < numberOfItems; i++)
{
ContextItem item = new ContextItem();
item.Work1 = DoSomeWorkWithLock;
item.Work2 = DoSomeWorkWithLock;
item.Work3 = DoSomeWorkWithLock;
}
Parallel.ForEach(items, (item) =>
{
item.Work1(null);
item.Work2(null);
item.Work3(null);
});
stopwatch.Stop();
Console.WriteLine("Time elapsed with locking: " + stopwatch.Elapsed);
}
private static void MeasureTimeWithCapuringContext()
{
List<ContextItem> items = new List<ContextItem>();
Stopwatch stopwatch = Stopwatch.StartNew();
for (int i = 0; i < numberOfItems; i++)
{
ContextItem item = new ContextItem();
item.Context1 = ExecutionContext.Capture();
item.Context2 = ExecutionContext.Capture();
item.Context3 = ExecutionContext.Capture();
item.Work1 = DoSomeWork;
item.Work2 = DoSomeWork;
item.Work3 = DoSomeWork;
}
foreach (ContextItem item in items)
{
ExecutionContext.Run(item.Context1, item.Work1, null);
ExecutionContext.Run(item.Context2, item.Work2, null);
ExecutionContext.Run(item.Context3, item.Work3, null);
}
stopwatch.Stop();
Console.WriteLine("Time elapsed with capturing context: " + stopwatch.Elapsed);
}
private static void DoSomeWork(object ignored)
{
Work();
}
private static void DoSomeWorkWithLock(object ignored)
{
lock (_lock)
{
Work();
}
}
private static void Work()
{
int count = 0;
for (int i = 0; i < _numberOfIterations; i++)
{
count ++;
}
}
private class ContextItem
{
public ExecutionContext Context1 { get; set; }
public ExecutionContext Context2 { get; set; }
public ExecutionContext Context3 { get; set; }
public ContextCallback Work1 { get; set; }
public ContextCallback Work2 { get; set; }
public ContextCallback Work3 { get; set; }
}
}结果如下:

因此,如果我做得对,捕获和执行排队平均要比锁定花费高出5倍。
同时也要回答我问题的一部分:
还是这听起来是完全错误的做法?
我在这篇文章上读到
如果你必须知道他们在那里,要么你在做一些超先进的事情,要么是出了问题。
如果您想了解ExecutionContext,那么推荐这篇文章作为最佳来源。在通过它并与一位同事一起运行一些测试之后,我意识到我使用的是ExecutionContext没有意义的地方,而且它比锁的性能更低,因此它可能也比其他线程功能/构造的性能更低。
https://stackoverflow.com/questions/34687336
复制相似问题