[英]C# Lock Threading
我目前正在嘗試閱讀一些有關C#中的線程鎖定的信息。
如果我有一個類似於下面的課程
public class Connection
{
bool Connected;
internal bool startConnection(Device dev)
{
// start connection
Connected = true;
}
internal bool endConnection(Device dev)
{
// End connection
Connected = false;
}
private void readFromConnected(Device dev)
{
if(Connected)
{
// read values from connected device
}
}
}
我現在遇到的問題是,我有多個線程使用此類從不同設備讀取值
當一個線程在實際斷開連接時嘗試讀取值,但又試圖讀取值時會出現問題,因為另一個線程將Connected bool設置為true。
調用此類的線程看起來像這樣。
Device deviceReceived;
public PollingInstance(Device deviceSent)
{
deviceReceived = deviceSent;
aTimer = new System.Timers.Timer(2500); //1000 = 1 sec
aTimer.Elapsed += OnTimedEvent;
aTimer.Enabled = true;
}
private void OnTimedEvent(Object source, ElapsedEventArgs e)
{
for (int i = 0; i < 10; i++)
{
Connection.startConnection(deviceReceived);
Connection.readFromConnected(deviceReceived);
Connection.endConnection(deviceReceived);
}
}
主類調用輪詢實例的部分看起來與此類似
foreach(Device dev in listOfDev)
{
Task.Factory.StartNew(() => pollThread(dev));
}
private void pollThread(Device dev)
{
PollingInstance testingPoll = new PollingInstance(dev);
}
簡單。 為什么connected
bool
?
嘗試這個。
public class Connection
{
private int _connections = 0;
internal bool startConnection(Device dev)
{
// start connection
if(Interlocked.Increment(ref _connections) == 1)
{
//do work to connect.
}
}
internal bool endConnection(Device dev)
{
// End connection
if(Interlocked.Decrement(ref _connections) == 0)
{
//do work to disconnect.
}
}
private void readFromConnected(Device dev)
{
if(_connections > 0)
{
// read values from connected device
}
}
}
這將對某些工作價值“起作用”。 但是由於異常和草率/健忘的編程,很容易使連接保持打開狀態。 因此,我建議以下幾點。
Device device = ...
using(var connection = device.CreateConnection())
{
var results = connection.Read();
}
public abstract class Connection : IDisposable
{
public object Read();
}
public class Device
{
private class DeviceConnection : Connection
{
private Device Parent { get; set; }
void Dispose()
{
Parent.StopConnection();
}
public object Read()
{
return Device.readFromConnected();
}
}
private int _connections = 0;
public Connection CreateConnection()
{
// start connection
if(Interlocked.Increment(ref _connections) == 1)
{
//do work to connect.
}
return new DeviceConnection { Parent = this };
}
private bool StopConnection()
{
// End connection
if(Interlocked.Decrement(ref _connections) == 0)
{
//do work to disconnect.
}
}
private object readFromConnected()
{
//Device is guaranteed to be connected now!
}
}
很難確切說明會發生什么,因為您發布的代碼甚至無法編譯。
你不會是這樣的:
private void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Connection connection = whereverThisComesFrom();
if(!Monitor.TryEnter(connection)) return; // another timer is in progress
try
{
for (int i = 0; i < 10; i++)
{
connection.startConnection(deviceReceived);
connection.readFromConnected(deviceReceived);
connection.endConnection(deviceReceived);
}
}
finally
{
Monitor.Exit(connection);
}
}
你說:
當一個線程在實際斷開連接時嘗試讀取值,但又試圖讀取值時會出現問題,因為另一個線程將Connected bool設置為true。
您是否可以嘗試/最終確保正確設置布爾值?
lock
關鍵字等效於Monitor try / finally。
object syncObject = new object();
Monitor.Enter(syncObject);
try {
// Code updating shared data
}
finally {
Monitor.Exit(syncObject);
}
object syncObject = new object();
lock (syncObject) {
// Code updating shared data
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.