请考虑以下内容:
//base stuff
private readonly ConcurrentQueue<message> queue = new ConcurrentQueue<message>();
private readonly MyCacheData _cache = new MyCacheData ();
//setuo
timer = new Timer { Interval = 60_000, AutoReset = true };
timer.Elapsed += OnTimedEvent;
httpClient.Timeout = new TimeSpan(0, 0, 60); // 60 seconds too
//
// each 60 seconds
private async void OnTimedEvent(object sender, ElapsedEventArgs e)
{
if (cache 30 minutes old)
{
//Fire and Forget GetWebDataAsync()
// and continue executing next stuff
// if I await it will wait 60 seconds worst case
// until going to the queue and by this time another
// timed even fires
}
// this always should execute each 60 seconds
if (queue isnt empty)
{
process queue
}
}
// heavy cache update each 10-30 minutes
private async Task GetWebDataAsync()
{
if (Semaphore.WaitAsync(1000))
{
try
{
//fetch WebData update cache
//populate Queue if needed
}
catch (Exception)
{
}
finally
{
release Semaphore
}
}
}
彩色:https://ghostbin.com/paste/6edov
因为我作弊并使用廉价的ConcurrentQueue解决方案,所以我不太在意GetWebDataAsync()期间发生的事情,所以我只想触发它并执行其工作,而我立即进入处理队列,因为它总是必须每60秒或计时器分辨率完成一次。
如何正确执行此操作,避免过多的开销或不必要的线程生成?
编辑:在其他地方为我的案件提供了答案
private async void OnTimedEvent(object sender, ElapsedEventArgs e)
{
async void DoGetWebData() => await GetWebDataAsync()
if (condition)
{
DoGetWebData(); // Fire&Forget and continue, exceptions handled inside
}
//no (a)waiting for the GetWebDataAsync(), we already here
if (queue isnt empty)
{
//process queue
}
}
private async Task GetWebDataAsync()
{
if (Semaphore.WaitAsync(1000))
{
try
{
//fetch WebData update cache
//populate Queue if needed
}
catch (Exception)
{
//log stuff
}
finally
{
///always release lock
}
}
}
答案 0 :(得分:1)
Task.Run(...);
ThreadPool.QueueUserItem(...);
这些有什么问题吗?...
那又怎么样呢?
ManualResetEvent mre = new ManualResetEvent(false);
void Foo()
{
new Thread(() =>
{
while (mre.WaitOne())
{
/*process queue item*/
if (/*queue is empty*/)
{
mre.Reset();
}
}
}) { IsBackground = true }.Start();
}
void AddItem()
{
/*queue add item*/
mre.Set();
}
答案 1 :(得分:0)
从另一个async
方法中调用一个async
方法没有 await
语句