Накрыли сомнения насчет CER
Мне нужно гарантировано выполнить две операции
1. Удалить из списка
2. Вставить обратно в голову списка
Обе операции безопасны с точки зрения исключений.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
}
finally
{
List__Remove(x);
List__PushFront(x);
}
//....
static void List__Remove(Node x)
{
//....
}
static void List__PushFront(Node x)
{
//....
}
Когда я из finally вызову методы List__xxxx, там внутри "CER" будет продолжать действовать?
Ну, то есть, всякие внешние "прерыватели" выполнения текущего потока подождут, пока не отработает finally?
Насколько я помню — да.
Но, повторюсь, накрыли сомнения, а снова грузить в себя документацию по этому поводу не хочется
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Накрыли сомнения насчет CER
КД>КД>RuntimeHelpers.PrepareConstrainedRegions();
КД>try
КД>{
КД>}
КД>finally
КД>{
КД> List__Remove(x);
КД> List__PushFront(x);
КД>}
КД>//....
КД>static void List__Remove(Node x)
КД>{
КД> //....
КД>}
КД>static void List__PushFront(Node x)
КД>{
КД> //....
КД>}
КД>
КД>Когда я из finally вызову методы List__xxxx, там внутри "CER" будет продолжать действовать?
Насколько я помню нужно весь call graph внутри CER помечать ReliabilityContractAttribute, методы List__Remove и List__PushFront должны стать типа
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
static void List__Remove(Node x)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
static void List__PushFront(Node x)
{
}
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Здравствуйте, romangr, Вы писали:
R>>Насколько я помню нужно весь call graph внутри CER помечать ReliabilityContractAttribute, методы List__Remove и List__PushFront должны стать типа
КД>Oh sh... Понакрутят жеж...
Microsoft перехреначил все ссылки на MSDN magazine, но я таки нашел статью —
Keep Your Code Running with the Reliability Features of the .NET Framework... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Здравствуйте, romangr, Вы писали:
R>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>Здравствуйте, romangr, Вы писали:
R>>>Насколько я помню нужно весь call graph внутри CER помечать ReliabilityContractAttribute, методы List__Remove и List__PushFront должны стать типа
КД>>Oh sh... Понакрутят жеж...
R>Microsoft перехреначил все ссылки на MSDN magazine, но я таки нашел статью — Keep Your Code Running with the Reliability Features of the .NET Framework
Спасибо за ссылку!
Вроде написано по делу. Но, .ля, голова упирается и не хочет это в себя засовывать
| Вот тот код про который упоминал в первом сообщении |
| private static void Helper__CacheList__BringToHead(Core_ConnectionOptions node)
{
Debug.Assert(!Object.ReferenceEquals(node,null));
RuntimeHelpers.PrepareConstrainedRegions(); //-------------------- CER
try
{
}
finally
{
Helper__CacheList__Remove__CER(node);
Helper__CacheList__PushFront__CER(node);
}//finally //-------------------- /CER
}//Helper__Cache__BringToHead
//-----------------------------------------------------------------------
private static void Helper__CacheList__Remove__CER(Core_ConnectionOptions node)
{
Debug.Assert(!Object.ReferenceEquals(node,null));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,null));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Tail,null));
if(Object.ReferenceEquals(sm_CacheList__Head,node))
{
//Remove from HEAD
Debug.Assert(Object.ReferenceEquals(node.m_List_Prev,null));
if(Object.ReferenceEquals(sm_CacheList__Tail,node))
{
Debug.Assert(Object.ReferenceEquals(node.m_List_Next,null));
sm_CacheList__Head=null;
sm_CacheList__Tail=null;
}
else
{
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,sm_CacheList__Tail));
var newHead=node.m_List_Next;
Debug.Assert(Object.ReferenceEquals(newHead.m_List_Prev,node));
newHead.m_List_Prev=null;
sm_CacheList__Head=newHead;
}//else
}
else
if(Object.ReferenceEquals(sm_CacheList__Tail,node))
{
//Remove from TAIL
Debug.Assert(Object.ReferenceEquals(node.m_List_Next,null));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,node));
var newTail=node.m_List_Prev;
Debug.Assert(Object.ReferenceEquals(newTail.m_List_Next,node));
newTail.m_List_Next=null;
sm_CacheList__Tail=newTail;
}
else
{
//Remove middle list item
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,sm_CacheList__Tail));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head.m_List_Next,sm_CacheList__Tail));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,sm_CacheList__Tail.m_List_Prev));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,node));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Tail,node));
Debug.Assert(!Object.ReferenceEquals(node.m_List_Prev,null));
Debug.Assert(!Object.ReferenceEquals(node.m_List_Next,null));
Debug.Assert(Object.ReferenceEquals(node.m_List_Prev.m_List_Next,node));
Debug.Assert(Object.ReferenceEquals(node.m_List_Next.m_List_Prev,node));
node.m_List_Prev.m_List_Next=node.m_List_Next;
node.m_List_Next.m_List_Prev=node.m_List_Prev;
}//else
node.m_List_Prev=null;
node.m_List_Next=null;
}//Helper__CacheList__Remove__CER
//-----------------------------------------------------------------------
private static void Helper__CacheList__PushFront__CER(Core_ConnectionOptions node)
{
Debug.Assert(!Object.ReferenceEquals(node,null));
Debug.Assert(Object.ReferenceEquals(node.m_List_Prev,null));
Debug.Assert(Object.ReferenceEquals(node.m_List_Next,null));
if(Object.ReferenceEquals(sm_CacheList__Head,null))
{
Debug.Assert(Object.ReferenceEquals(sm_CacheList__Tail,null));
sm_CacheList__Head=node;
sm_CacheList__Tail=node;
return;
}//if
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,null));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Tail,null));
Debug.Assert(!Object.ReferenceEquals(sm_CacheList__Head,node));
node.m_List_Next=sm_CacheList__Head;
sm_CacheList__Head.m_List_Prev=node;
sm_CacheList__Head=node;
}//Helper__CacheList__PushFront__CER
|
| |
Я вот теперь думаю, чтобы устранить какие-либо сомнения — эти два метода (Remove и PushFront) стоит встроить прямо в блок finally?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --