C #: จะเกิดอะไรขึ้นถ้ามีการเรียกวิธีการแบบคงที่จากหลายเธรด?


95

ในแอปพลิเคชันของฉันฉันมีวิธีการแบบคงที่ซึ่งเรียกใช้จากหลายเธรดในเวลาเดียวกัน ข้อมูลของฉันจะถูกปะปนหรือไม่?

ในความพยายามครั้งแรกของฉันวิธีนี้ไม่คงที่และฉันกำลังสร้างหลายอินสแตนซ์ของคลาส ในกรณีนั้นข้อมูลของฉันก็ปนกัน ฉันไม่แน่ใจว่าสิ่งนี้เกิดขึ้นได้อย่างไรเพราะมันเกิดขึ้นเพียงบางครั้งเท่านั้น ฉันยังคงแก้ไขข้อบกพร่องอยู่ แต่ตอนนี้วิธีนี้เป็นแบบคงที่ฉันไม่มีปัญหาแล้ว บางทีมันอาจจะเป็นแค่โชค ไม่รู้แน่ชัดว่า


คำตอบ:


99

ตัวแปรที่ประกาศภายในเมธอด (ยกเว้นตัวแปร " จับ " ที่เป็นไปได้) จะถูกแยกออกดังนั้นคุณจะไม่ได้รับปัญหาใด ๆ อย่างไรก็ตามหากวิธีการคงที่ของคุณเข้าถึงสถานะที่ใช้ร่วมกันการเดิมพันทั้งหมดจะถูกปิด

ตัวอย่างของสภาวะที่ใช้ร่วมกันจะเป็น:

  • เขตข้อมูลคงที่
  • วัตถุที่เข้าถึงได้จากแคชทั่วไป (ไม่ต่ออนุกรม)
  • ข้อมูลที่ได้รับจากพารามิเตอร์อินพุต (และสถานะบนวัตถุเหล่านั้น) หากเป็นไปได้ว่าหลายเธรดกำลังสัมผัสกับวัตถุเดียวกัน

หากคุณมีสถานะที่ใช้ร่วมกันคุณต้อง:

  • ระวังอย่าให้สถานะกลายพันธุ์เมื่อสามารถใช้ร่วมกันได้ (ดีกว่า: ใช้วัตถุที่ไม่เปลี่ยนรูปเพื่อแสดงสถานะและถ่ายภาพรวมของสถานะลงในตัวแปรท้องถิ่น - กล่าวคือแทนที่จะอ้างอิงwhatever.SomeDataซ้ำ ๆ คุณอ่านwhatever.SomeData ครั้งเดียวเป็นตัวแปรท้องถิ่นแล้ว เพียงแค่ใช้ตัวแปร - โปรดทราบว่าสิ่งนี้ช่วยสำหรับสถานะที่ไม่เปลี่ยนรูปเท่านั้น!)
  • ซิงโครไนซ์การเข้าถึงข้อมูล (เธรดทั้งหมดต้องซิงโครไนซ์) - ตัวอ่าน / นักเขียนที่ไม่ซ้ำกันหรือ (ละเอียดมากขึ้น)

1
@Diego - ความคิดเห็นนั้นมีไว้สำหรับฉันหรือเพื่อ @Holli?
Marc Gravell

สำหรับ Holli เพียงเพิ่มข้อมูลที่เป็นประโยชน์ในการตอบกลับของคุณ
Diego Pereyra

1
@Marc ฉันไม่สามารถเห็นด้วยอย่างเต็มที่กับ "ตัวแปรที่ประกาศภายในวิธีการ (ยกเว้นตัวแปร" จับ "ที่เป็นไปได้) จะถูกแยกออก" พิจารณาตัวจัดการไฟล์ที่ประกาศด้วยวิธีการแบบคงที่ จากนั้นเธรดหนึ่งอาจเข้าถึงแฮนเดิลเมื่อมีเธรดอื่นใช้ มันจะนำไปสู่พฤติกรรมที่ไม่คาดคิด หรือตัวแปรที่ "บันทึก" ของคุณหมายถึง "file handle" ด้วย
prabhakaran

9
@prabhakaran ถ้าจัดการไฟล์เป็นตัวแปรวิธีการก็จะกำหนดขอบเขตเพียงการโทรที่ ผู้โทรคนอื่น ๆ จะคุยกับตัวแปรอื่น (ตัวแปรวิธีคือต่อการโทร) ตอนนี้การเข้าถึงไฟล์พื้นฐานเป็นปัญหาแยกต่างหาก แต่ไม่เกี่ยวข้องกับ c # หรือ. NET หากแฮนเดิลไม่ได้ใช้ร่วมกันใครจะคาดหวังว่าจะมี mutex / lock บางประเภทหากสถานการณ์นี้เป็นไปได้
Marc Gravell

29

ใช่มันเป็นเพียงโชค ;)

ไม่สำคัญว่าวิธีการนั้นจะเป็นแบบคงที่หรือไม่สิ่งที่สำคัญคือข้อมูลจะคงที่หรือไม่

หากแต่ละเธรดมีอินสแตนซ์ของคลาสแยกกันโดยมีชุดข้อมูลเป็นของตัวเองจะไม่มีความเสี่ยงที่ข้อมูลจะปะปนกัน หากข้อมูลเป็นแบบคงที่จะมีข้อมูลเพียงชุดเดียวและเธรดทั้งหมดแชร์ข้อมูลเดียวกันดังนั้นจึงไม่มีวิธีใดที่จะไม่ปะปนกัน

เมื่อข้อมูลของคุณในอินสแตนซ์แยกกันยังคงปะปนกันเป็นไปได้มากว่าเนื่องจากข้อมูลไม่ได้แยกจากกันจริงๆ


7
ชอบแนวนั้น - It doesn't matter if the method is static or not, what matters is if the data is static or not. เพียงเพื่อเพิ่มตัวแปรท้องถิ่นที่ประกาศภายในขอบเขตของวิธีการแบบคงที่ไม่ได้เป็นส่วนหนึ่งของข้อมูลที่เราต้องใส่ใจในสถานการณ์ที่กำหนด
RBT

คำตอบที่ดี ช่วยออกมามากมาย
Fractal

15

วิธีการคงที่ควรใช้ได้สำหรับหลายเธรด

ในทางกลับกันข้อมูลแบบคงที่อาจทำให้เกิดปัญหาได้เนื่องจากความพยายามในการเข้าถึงข้อมูลเดียวกันจากเธรดที่แตกต่างกันจำเป็นต้องได้รับการควบคุมเพื่อให้แน่ใจว่ามีเธรดเดียวเท่านั้นที่อ่านหรือเขียนข้อมูล


2
คำสำคัญที่นี่คือการซิงโครไนซ์ :-)
G.Stoynev

2
การอ่านตกลงที่จะเกิดขึ้นพร้อมกัน แต่การอ่านและการเขียนพร้อมกันจะนำไปสู่พฤติกรรมที่ไม่คาดคิด
Freestyle076

10

MSDN พูดเสมอว่า:

สมาชิกแบบคงที่สาธารณะ (ที่ใช้ร่วมกันใน Visual Basic) ประเภทนี้ปลอดภัยเธรด ไม่รับประกันว่าสมาชิกอินสแตนซ์ใด ๆ จะปลอดภัยต่อเธรด

แก้ไข: ตามที่พวกเขากล่าวไว้ไม่ได้เป็นเช่นนั้นเสมอไปและเห็นได้ชัดว่าสิ่งนี้ใช้กับคลาสที่ออกแบบด้วยวิธีนี้ใน BCL ไม่ใช่กับคลาสที่ผู้ใช้สร้างขึ้นซึ่งไม่สามารถใช้งานได้


3
วุ้ย ในที่สุดฉันก็เข้าใจความหมายของบันทึกนี้ซึ่งพบได้บ่อยในเอกสาร MSDN ดังนั้นโดยพื้นฐานแล้วเมื่อ MS ออกแบบวิธีการแบบคงที่ (ซึ่งมีการเผยแพร่บันทึกย่อนี้) ใน BCL พวกเขาจะไม่เข้าถึงตัวแปร / สมาชิก / สถานะใด ๆ ที่อยู่นอกขอบเขตของวิธีการนั้น พวกเขาอาศัยตัวแปรโลคัลที่กำหนดขอบเขตเมธอดอย่างสมบูรณ์สำหรับการใช้ตรรกะของวิธีนั้นเท่านั้น ดีใจมากที่คุณแบ่งปัน
RBT

@ มาร์โคตตรงข้ามไม่จริงเหรอ? สมาชิกอินสแตนซ์ปลอดภัยเนื่องจากมีหนึ่งอินสแตนซ์ อย่างไรก็ตามสมาชิกแบบคงที่ไม่ปลอดภัยเธรดเนื่องจากมีการใช้ร่วมกันระหว่างอินสแตนซ์ทั้งหมดของคลาสนั้น? quora.com/…
Fractal

1
มันขึ้นอยู่กับ. ฉันจะไม่ปฏิบัติต่อสมาชิกอินสแตนซ์อย่างปลอดภัยโดยปริยาย นั่นเป็นเหตุผลที่ไลบรารีทั้งชุดและเพื่อหลีกเลี่ยงความเสียหายของข้อมูลท่ามกลางสิ่งอื่น ๆ อีกมากมาย
Marcote

1
โอเคขอบคุณ @Marcote ฉันค่อยๆรู้ว่าฉันมีอะไรต้องเรียนรู้อีกมากมาย
Fractal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.