我有一个程序正在执行长时间运行的任务,应在程序启动时启动它,并且有可能在此后的任何时刻重新启动。
我的目的是如果调用“重新启动”,则会发生这种情况:
我想使用async / await并仍然锁定启动所有任务的过程,以确保在先前的启动/重新启动完成之前不会进行任何重新启动。
由于许多原因,我看到async / await不适用于锁statemnts,因此我最终使用了SemaphoreSlim,它对我来说非常有用。这是我的代码:
private readonly SemaphoreSlim m_semaphoreSlim;
private CancellationTokenSource m_cancellationTokenSource;
private CancellationToken m_cancellationToken;
public FeedClientService(IList<IFeedConfigurationBuilder> feedConfigs)
{
m_semaphoreSlim = new SemaphoreSlim(1, 1);
m_feedConfigs = feedConfigs;
}
public void Start()
{
Task.Run(() => this.FetchFeeds());
}
public void Restart()
{
if (m_cancellationTokenSource != null) m_cancellationTokenSource.Cancel();
Task.Run(() => this.FetchFeeds());
}
private async Task FetchFeeds()
{
try
{
await m_semaphoreSlim.WaitAsync();
m_cancellationTokenSource = new CancellationTokenSource();
m_cancellationToken = m_cancellationTokenSource.Token;
Task[] tasks = new Task[m_feedConfigs.Count];
for (int i = 0; i < m_feedConfigs.Count; i++)
{
var index = i;
tasks[index] = Task.Run(async () => await this.FetchFeed(index), m_cancellationToken);
}
await Task.WhenAll(tasks);
}
finally
{
m_semaphoreSlim.Release();
}
}
这里指出https://stackoverflow.com/a/4154526/4664866-“ SemaphoreSlim类表示轻量级,快速的信号量,当预期等待时间很短时,可用于在单个进程中等待”。我没有找到任何指定了“非常简短”的资源,而且我不确定我的代码是否不会出现性能瓶颈,因为我正在启动的任务肯定不会短暂运行。
TL; DR;
答案 0 :(得分:1)
事实证明,SemaphoreSlim.WaitAsync
根本没有使用自旋等待技术(仅供参考-implementation of SemaphoreSlim)。因此,锁定资源,即使其中包含长时间运行的任务,也不会影响CPU消耗。