РЕДАКТИРОВАТЬ : нашел ответ - https://www.youtube.com/watch?v=8aGhZQkoFbQ
_
Хорошо, поэтому у меня есть некоторый фон C #, и C # "асинхронная среда" немногосмешанный пакет параллелизма и « малый параллелизм », т. е. когда речь идет о тяжелой асинхронной среде, вы можете иметь условия гонки, тупик и вам необходимо защищать общие ресурсы.
Теперь я пытаюсь понять, как работает асинхронная среда JavaScript / ES6.Рассмотрим следующий код:
// current context: background "page"
// independent from content page
let busy = false;
// This is an event handler that receives event from content page
// It can happen at any time
runtimeObj.onMessage.addListener((request) =>
{
if(request.action === 'AddEntry')
{
AddEntry(request);
return true;
}
return false;
} );
function AddEntry(data)
{
if (!busy)
group.push({url: data.url, time: Date.now(), session: data.session});
else
setTimeout(AddEntry(data),10000) // simulating Semaphore wait
}
// called from asynchronous function setInterval()
function SendPOST()
{
if (groups.length < 1 || groups === undefined)
return;
busy = true; // JS has no semaphores so I "simulate it"
let del = [];
groups.forEach(item =>
{
if (Date.now() - item.time > 3600000)
{
del.push(item);
let xhr = new XMLHttpRequest();
let data = new FormData();
data.append('action', 'leave');
data.append('sessionID', item.session);
xhr.withCredentials = true;
http.onreadystatechange = function()
{
if(http.readyState == 4 && http.status !== 200) {
console.log(`Unable to part group ${item.url}! Reason: ${http.status}. Leave group manually.`)
}
}
xhr.open('POST', item.url, true);
xhr.send(data);
}
});
del.forEach(item => groups.slice(item,1));
busy = false;
}
setInterval(SendPOST, 60000);
Это на самом деле не лучший пример, так как в нем нет набора асинхронных ключевых слов в паре с функциями, но, на мой взгляд, и sendPost()
, и AddEntry()
не являются действительно чистыми последовательными операциями.,Тем не менее, мне сказали, что в AddEntry()
, busy
всегда будет false
, потому что:
sendPost ставится в очередь для выполнения в минуту
событиедобавить в цикл событий
событие обрабатывается и AddEntry вызывается
, так как busy = false, группа выталкивается
проходит минута и SendPost добавляется в цикл событий
событие является процессом, и SendPost называется
groups.length === 1, поэтому оно продолжается
busy = true
каждая группа вызывает запросчтобы получить в очередь
событие приходит в
busy = false
событие обрабатывается, AddEntry вызывается
busy = false, как всегдаbe
группа выталкивается
, в конце концов, запросы из ранее разрешаются, и обратные вызовы onreadystatechange помещаются в цикл обработки событий
, в конце концов каждый из обратных вызовов обрабатывается иоператоры журнала выполняются
Это правильно?Из того, что я понимаю, это, по сути, означает, что не может быть никаких условий гонки или тупика, или мне когда-либо нужно защищать общий ресурс.
Если меня двое, напишите аналогичный код для среды выполнения C #, где sendPost()
и AddEntry()
- это асинхронные методы задач, которые можно вызывать неблокирующим способом из разных источников событий может ситуация, когда я получаю доступ к общему ресурсу, в то время как контекст итерации временно приостанавливается при переключении контекста посредством Thread Sheduler.