在一次运行中执行一段代码,而不为其他并行线程阻塞它



假设您在一个方法中有一段代码,它不使用任何关键资源,但是您想在一次运行中执行它,因为您想确保代码尽可能快地执行,而不会因为调度而导致任何暂停。

如果您像下面这样使用lockSemaphoreSlim,它们中的代码将被每个并行运行的其他线程阻塞,这将对性能产生负面影响。当然,SemaphoreSlim提供了定义并行线程数量的可能性,但我不想自己管理它。

private readonly object myLock = new object();
lock (this.teamLock)
{
// ... code
}
// 
private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
public async Task LockAsync(Func<Task> worker)
{
await semaphore.WaitAsync();
try
{
// ... code
}
finally
{
semaphore.Release();
}
}

是否有其他方法可以确保代码在一次运行中执行?

你可能不想这样做,即使你这样做了,也可能不值得。

。. NET线程由操作系统线程支持,操作系统线程使用抢占式调度(你要问的是如何防止抢占)。

你可以通过挂起其他线程来阻止它们在同一个应用程序中运行。您需要下拉到Win32级别才能枚举和挂起它们。但是,如果希望运行托管代码,这可能会导致死锁,因为运行时通常假定其线程正在运行。还有其他应用程序的其他线程。

或者,如果您在Windows上,您可以将线程优先级提高到实时级别以上,以避免其他线程获得与您的线程相同的动态优先级。但是,通常不建议这样做,对于托管代码更是如此,原因与上面的死锁相同。缺乏动态提升可能会导致死锁,除非您非常小心。使用实时优先级需要完全理解所有的依赖项,以及它们如何与实时优先级线程交互。

所以,虽然这在技术上是可能的,但这是相当多的工作;而且它根本不应该是托管代码,因为运行时不是为此设计的。您可以将其重写为非托管代码,然后在单独的实时进程中运行它。然后验证您的依赖项是否会按预期工作。

你想在一次运行中执行它,因为你想确保代码尽可能快地执行,而不会因为调度而暂停。

实际上,应该做的可能是降低的优先级,或者保持默认值。动态优先级提升将自动为用户提供最佳选择。如果有的话,如果您有一个cpu受限的方法,需要花费相当多的时间,请考虑降低的优先级。

最新更新