我有一個需要很長時間才能初始化的對象。因此,我有能力在應用程序啓動時啓動初始化。任何後續對類上的方法的調用,我們都需要有一個延遲機制,等待類完成初始化。是否有一個在後臺線程上初始化對象的常用模式?
我有一些潛在的解決方案,但我不完全滿意他們中的任何一個。第一個在while循環中使用Task.Delay,第二個使用SemaphoreSlim,但涉及一些不必要的阻塞。我覺得這一定是一個相當普遍的要求,任何人都可以提供一些關於如何最好地管理這個問題的建議?
哦順便說一句,這是一個地鐵應用,所以我們只有有限的API的
這裏是僞代碼:
public class ExposeSomeInterestingItems
{
private InitialisationState _initialised;
private readonly SemaphoreSlim _waiter =
new SemaphoreSlim(0);
public async Task StartInitialize()
{
if (_initialised == InitialisationState.Initialised)
{
throw new InvalidOperationException(
"Attempted to initialise ActiveTrackDown" +
"loads when it is already initialized");
}
_initialised =
InitialisationState.StartedInitialisation;
new TaskFactory().StartNew(async() =>
{
// This takes some time to load
this._interestingItems =
InterestingItemsLoader.LoadItems();
_waiter.Release();
_initialised = InitialisationState.Initialised;
});
}
public InterestingItem GetItem(string id)
{
DelayUntilLoaded();
DelayUntilLoadedAlternative();
}
private async Task DelayUntilLoaded()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException("Error " +
"occurred attempting to access details on " +
"ActiveTrackDownloads before calling initialise");
}
while (true)
{
if (_initialised == InitialisationState.Initialised)
{
return;
}
await Task.Delay(300);
}
}
private async Task DelayUntilLoadedAlternative()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException(
"Error occurred attempting to access details " +
"on ActiveTrackDownloads before calling initialise");
}
try
{
await _waiter.WaitAsync();
}
finally
{
_waiter.Release();
}
}
}
如何不讓實例可用(保持爲空)直到它完成? –