[英]C# Lock Threading
I am currently trying to do some reading for locking for threads in C# . 我目前正在尝试阅读一些有关C#中的线程锁定的信息。
If I have a class similar to below 如果我有一个类似于下面的课程
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
}
}
}
The problem I have right now is that i have multiple threads using this class to read values from different devices 我现在遇到的问题是,我有多个线程使用此类从不同设备读取值
A problem arises when a thread tries to read values when it is actually disconnected, but attempts to read the values anyways because another thread has kept the Connected bool to true; 当一个线程在实际断开连接时尝试读取值,但又试图读取值时会出现问题,因为另一个线程将Connected bool设置为true。
The thread that is calling this class looks like this. 调用此类的线程看起来像这样。
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);
}
}
The part of the main class calling Polling Instance looks similar to this 主类调用轮询实例的部分看起来与此类似
foreach(Device dev in listOfDev)
{
Task.Factory.StartNew(() => pollThread(dev));
}
private void pollThread(Device dev)
{
PollingInstance testingPoll = new PollingInstance(dev);
}
Simple. 简单。 Why is
connected
a bool
? 为什么
connected
bool
?
Try this. 尝试这个。
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
}
}
}
This will "works" for some values of work. 这将对某些工作价值“起作用”。 But is prone to connections being left open due to exceptions and sloppy/forgetful programming.
但是由于异常和草率/健忘的编程,很容易使连接保持打开状态。 Therefore I would advise the following.
因此,我建议以下几点。
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!
}
}
It's hard to say exactly what will happen, because the code you posted won't even compile. 很难确切说明会发生什么,因为您发布的代码甚至无法编译。
you wan't something like this: 你不会是这样的:
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);
}
}
You said: 你说:
A problem arises when a thread tries to read values when it is actually disconnected, but attempts to read the values anyways because another thread has kept the Connected bool to true;
当一个线程在实际断开连接时尝试读取值,但又试图读取值时会出现问题,因为另一个线程将Connected bool设置为true。
Can you use a try/finally to ensure you set the boolean properly? 您是否可以尝试/最终确保正确设置布尔值?
The lock
keyword is equivalent to a Monitor try/finally. 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.