дазволу канфліктаў шматструменнасці ў C #

дазваляе выказаць здагадку, ёсць статычная пераменная доступ 2 патокаў.

public static int val = 1;

Зараз выкажам здагадку, што нітка 1 выканаць гэтую заяву, як гэта

if(val==1)
{
  val +=1
}

Аднак пасля праверкі і перад даданнем у вышэй згаданым заяве ніткі 2 змяняе значэнне Вала да чаго-небудзь яшчэ.

Цяпер, можа выклікаць некаторыя непрыемныя памылкі. І гэта адбываецца ў маім кодзе.

Ці ёсць спосаб, што нітка 1 атрымлівае заўважыла, што значэнні Вала былі змененыя, і замест дадання ідзе назад і зноў выконвае праверку.

1
Грунтуючыся на ваша пытанне, я хацеў бы прапанаваць Interlocked.CompareExchange , як гэта рэкамендавана ў адказ ніжэй. Калі вы думаеце, што гэта не падыходзіць, вы павінны змяніць сваё пытанне, каб паказаць нам <�я> рэальны </я> праблема, якую вы спрабуеце вырашыць.
дададзена аўтар Jim Mischel, крыніца
Грунтуючыся на ваша пытанне, я хацеў бы прапанаваць Interlocked.CompareExchange , як гэта рэкамендавана ў адказ ніжэй. Калі вы думаеце, што гэта не падыходзіць, вы павінны змяніць сваё пытанне, каб паказаць нам <�я> рэальны </я> праблема, якую вы спрабуеце вырашыць.
дададзена аўтар Jim Mischel, крыніца

7 адказы

Спецыяльна для вашага прыкладу, вы можаце:

var originalValue = Interlocked.CompareExchange(ref val, 
                                    2,       //update val to this value
                                    1);      //if val matches this value
if(originalValue == 1)
{
    //the update occurred
}
6
дададзена
а мой прыклад проста спрошчаная версія гэтай праблемы я сутыкнуўся ў маім кодзе. Я не думаю, што вышэй метад будзе вельмі лёгка выкарыстоўваць у маім рэальным кодзе.
дададзена аўтар Win Coder, крыніца
@WinCoder: Паглядзіце на тое, што Interlocked можа прапанаваць, таму што ён усё яшчэ можа мець інструменты, каб задаволіць вашыя патрэбы.
дададзена аўтар spender, крыніца

Вы можаце выкарыстоўваць блакаванне:

var lockObj = new object();

if(val == 1)//is the value what we want
{
    lock(lockObj)//let's lock it
    {
        if(val == 1)//now that it's lock, check again just to be sure
        {
            val += 1;
        }
    }
}

Калі ісці па гэтым шляху, вы павінны пераканацца, што любы код, які мадыфікуе Вэл таксама выкарыстоўвае блакаванне з тым жа аб'ектам блакавання.

lock(lockObj)
{
   //code that changes `val`
}
3
дададзена
Ці не здаецца выдатнай ідэяй, каб праверыць значэнне Вале па-за замка, а затым зрабіць гэта зноў ўнутры замка. Калі вы паставіце кожны доступ да вала ўнутры замка, ці з'яўляецца ён чытаць і пісаць, вам не трэба турбавацца аб кім-то важдацца з ім, перш чым дакрануцца да яе. Такім чынам, вы атрымаеце блакаванне, а затым праверыць Валя, і вы можаце быць упэўнены, што ніхто не кранае Вэл, перш чым рабіць.
дададзена аўтар Michael Mankus, крыніца
Добрае пытанне. Я ніколі не пераправерыў вакол маіх замкаў. Падобна на тое, гэта тое, што я пачну рабіць.
дададзена аўтар Michael Mankus, крыніца
@JimMischel - я выкарыстаў замак проста таму, што мяркуецца, што гэта спрошчаны прыклад. Калі OP сапраўды толькі павялічваецца значэнне, то, вядома, будзе ісці з Iterlocked.CompareExchange або метадам Interlocked.Increment.
дададзена аўтар Justin Niessner, крыніца
@MichaelMankus - У вашым выпадку, вы завяршаеце з замкам ці трэба вам гэта ці не. Праверка значэння, як правіла, недарагія у той час як з замкам з'яўляецца больш дарагім і можа змясціць іншы код чакання для блакавання. Праверце развагі на en.wikipedia.org/wiki/Double-checked_locking
дададзена аўтар Justin Niessner, крыніца
Я не магу зразумець, чаму вы б выкарыстоўваць блакаванне тут замест Interlocked.CompareExchange .
дададзена аўтар Jim Mischel, крыніца

Вы можаце выкарыстоўваць блакаванне:

var lockObj = new object();

if(val == 1)//is the value what we want
{
    lock(lockObj)//let's lock it
    {
        if(val == 1)//now that it's lock, check again just to be sure
        {
            val += 1;
        }
    }
}

Калі ісці па гэтым шляху, вы павінны пераканацца, што любы код, які мадыфікуе Вэл таксама выкарыстоўвае блакаванне з тым жа аб'ектам блакавання.

lock(lockObj)
{
   //code that changes `val`
}
3
дададзена
Ці не здаецца выдатнай ідэяй, каб праверыць значэнне Вале па-за замка, а затым зрабіць гэта зноў ўнутры замка. Калі вы паставіце кожны доступ да вала ўнутры замка, ці з'яўляецца ён чытаць і пісаць, вам не трэба турбавацца аб кім-то важдацца з ім, перш чым дакрануцца да яе. Такім чынам, вы атрымаеце блакаванне, а затым праверыць Валя, і вы можаце быць упэўнены, што ніхто не кранае Вэл, перш чым рабіць.
дададзена аўтар Michael Mankus, крыніца
Добрае пытанне. Я ніколі не пераправерыў вакол маіх замкаў. Падобна на тое, гэта тое, што я пачну рабіць.
дададзена аўтар Michael Mankus, крыніца
@JimMischel - я выкарыстаў замак проста таму, што мяркуецца, што гэта спрошчаны прыклад. Калі OP сапраўды толькі павялічваецца значэнне, то, вядома, будзе ісці з Iterlocked.CompareExchange або метадам Interlocked.Increment.
дададзена аўтар Justin Niessner, крыніца
@MichaelMankus - У вашым выпадку, вы завяршаеце з замкам ці трэба вам гэта ці не. Праверка значэння, як правіла, недарагія у той час як з замкам з'яўляецца больш дарагім і можа змясціць іншы код чакання для блакавання. Праверце развагі на en.wikipedia.org/wiki/Double-checked_locking
дададзена аўтар Justin Niessner, крыніца
Я не магу зразумець, чаму вы б выкарыстоўваць блакаванне тут замест Interlocked.CompareExchange .
дададзена аўтар Jim Mischel, крыніца

Вы можаце выкарыстоўваць блакаванне:

var lockObj = new object();

if(val == 1)//is the value what we want
{
    lock(lockObj)//let's lock it
    {
        if(val == 1)//now that it's lock, check again just to be sure
        {
            val += 1;
        }
    }
}

Калі ісці па гэтым шляху, вы павінны пераканацца, што любы код, які мадыфікуе Вэл таксама выкарыстоўвае блакаванне з тым жа аб'ектам блакавання.

lock(lockObj)
{
   //code that changes `val`
}
3
дададзена
Ці не здаецца выдатнай ідэяй, каб праверыць значэнне Вале па-за замка, а затым зрабіць гэта зноў ўнутры замка. Калі вы паставіце кожны доступ да вала ўнутры замка, ці з'яўляецца ён чытаць і пісаць, вам не трэба турбавацца аб кім-то важдацца з ім, перш чым дакрануцца да яе. Такім чынам, вы атрымаеце блакаванне, а затым праверыць Валя, і вы можаце быць упэўнены, што ніхто не кранае Вэл, перш чым рабіць.
дададзена аўтар Michael Mankus, крыніца
Добрае пытанне. Я ніколі не пераправерыў вакол маіх замкаў. Падобна на тое, гэта тое, што я пачну рабіць.
дададзена аўтар Michael Mankus, крыніца
@JimMischel - я выкарыстаў замак проста таму, што мяркуецца, што гэта спрошчаны прыклад. Калі OP сапраўды толькі павялічваецца значэнне, то, вядома, будзе ісці з Iterlocked.CompareExchange або метадам Interlocked.Increment.
дададзена аўтар Justin Niessner, крыніца
@MichaelMankus - У вашым выпадку, вы завяршаеце з замкам ці трэба вам гэта ці не. Праверка значэння, як правіла, недарагія у той час як з замкам з'яўляецца больш дарагім і можа змясціць іншы код чакання для блакавання. Праверце развагі на en.wikipedia.org/wiki/Double-checked_locking
дададзена аўтар Justin Niessner, крыніца
Я не магу зразумець, чаму вы б выкарыстоўваць блакаванне тут замест Interlocked.CompareExchange .
дададзена аўтар Jim Mischel, крыніца

If you wish to increment an integral value in a thread-safe way, you can use the static Interlocked.Increment method: Interlocked.Increment Method (Int32)

0
дададзена

You could use a lock around accessing val or updating val. See http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

0
дададзена

You could use a lock around accessing val or updating val. See http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

0
дададзена