【发布时间】:2013-03-31 20:51:00
【问题描述】:
我一直在尝试按照以下方式进行工作,这是一个完整的代码示例,可以在 Visual Studio 中运行,它演示了我正在谈论的场景。这里的一切都按预期工作,当我更改播放器的 IsReady 值时,附加到事件的 lambda 被触发并且 if (to) 评估为 true。但是 Console.WriteLine 永远不会被命中,因为 ConcurrentBag 中播放器的 IsReady 值似乎没有更新。
class Program
{
public static ConcurrentBag<Player> Players { get; set; }
static void Main(string[] args)
{
Players = new ConcurrentBag<Player>();
Player player = new Player() { Id = "123" };
Players.Add(player);
player.IsReady.ValueChanged += (from, to) =>
{
if (to)
{
if (Players.All(p => p.IsReady.Value))
{
Console.WriteLine("It worked");
}
}
};
LookupPlayerById("123").IsReady.Value = true;
}
public static Player LookupPlayerById(string clientId)
{
var player = Players.FirstOrDefault(x => x.Id == clientId);
return player;
}
}
public class Player
{
public string Id { get; set; }
public MonitoredValue<bool> IsReady { get; set; }
public Player()
{
IsReady = new MonitoredValue<bool>(false);
}
}
public class MonitoredValue<T>
{
public delegate void ValueChangedHandler(T from, T to);
public event ValueChangedHandler ValueChanged;
private T m_Value;
public T Value
{
get { return m_Value; }
set
{
if (ValueChanged != null) // if invocation list is not empty, fire the event
{
ValueChanged(m_Value, value);
}
m_Value = value;
}
}
public MonitoredValue() { }
public MonitoredValue(T initialValue)
{
m_Value = initialValue;
}
}
【问题讨论】:
-
Player是class还是struct? -
然后你返回一个
reference给一个 Player 对象。更改它的状态将影响同一个对象,即来自ConcurrentBag<Player>的链接的存储内容 -
如果您知道使用 C# 和 LINQ 执行此操作的方法,请分享。那是我尝试做的第一件事,但这似乎是技术的限制?我必须以某种方式使用吗?我的印象是返回 FirstOrDefault() 会阻止您使用引用
-
IsReady是什么类型? -
if (Players.All(p => p.IsReady.Value))
标签: c# linq collections