Пока я проверял работу своего кода, я обнаружил очень интересный фрагмент кода, который, клянусь, может вызвать тупик, но я проверял его много раз с несколькими потоками и не смог его получить.
это меня так озадачивает, что я решил спросить это здесь.
Итак, предположение, что LOCK не блокируется для того же потока, но я хотел бы подтвердить это.
После фрагмента кода
public class SplitService : ISplitService
{
private IRecordService recordService;
public SplitService(IRecordService recordService)
{
this.recordService = recordService;
}
private ConcurrentQueue<Batch> _batches = new ConcurrentQueue<Batch>();
public void Feed(Something r)
{
lock (this.recordService)
{
if (!this.recordService.CanAppend(r))
{
Flush();
}
this.recordService.Append(r);
}
}
public void Flush()
{
lock (this.recordService)
{
if (!this.recordService.Any()) return;
var record = this.recordService.GetBatch();
_batches.Enqueue(record);
this.recordService.Clean();
}
}
public IEnumerable<Batch> Get()
{
while (_batches.Any())
{
if (_batches.TryDequeue(out Batch batch))
{
yield return batch;
}
}
}
}
Как вы можете заметить, метод Feed
блокируется в объекте , и если то же самое возвращает false для CanAppend, он вызывает метод Flush
, который также попробуйте заблокировать тот же объект . Так что я бы ожидал там тупика
После некоторого понимания экстраполяции, поскольку Lock рекурсивен, мы можем предположить, что это также будет работать:
lock(locker){
Console.WriteLine("Hello World");
await new Task(() => {
lock(locker){
Console.WriteLine("Hello World from locker");
}
});
}