我有一个使用WCF的服务器客户端。
服务器有一个客户列表。
要检查超时,每分钟都会向每个客户端发送一些数据(ping)。所有发送都是异步完成的 - 因此该行如下所示:
for (int i = 0; i < MaxUsers; i++)
{
if (_clients[i] != null)
{
_clients[i].Client.BeginSendToClient("PING", new AsyncCallback(this.SendToClientCallback), _clients[i].Client);
现在,SentToClientCallback方法就像这样开始:
void SendToClientCallback(IAsyncResult asyncResult)
{
IClientAsync callback = null;
try
{
callback = (IClientAsync)asyncResult.AsyncState;
callback.EndSendToClient(asyncResult);
}
catch (TimeoutException e)
超时异常必须将我们发回的结果转换为在_client数组中获取客户端的索引...并且它使用我写的方法来实现:
int myClientIndex = GetClientIndexFromCallback(CurrentCallback);
,其中
private int GetClientIndexFromCallback(IClientAsync callback)
{
for (int i = 0; i < MaxUsers; i++)
{
if (_clients[i] != null && _clients[i].Client.Equals(callback))
{
// found
return i;
现在这个代码可以正常工作,如果我连接,然后断开连接。它发送PING,转到回调方法。它会生成超时异常。它获取id号(为0)并删除_client [0],一切都很好。
但是,如果我连续两次连接和断开连接,则在第一次连接超时之前,只有一个连接(第二个连接或_client [1])断开连接。另一个仍然存在,并不断被发送PING。
回调方法继续运行,并继续生成超时异常...但是当我调用我的方法获取它的id时,它无法找到它。出于某种原因,_clients[i].Client.Equals(callback)
未返回true。
这怎么可能?每个PING命令都会发送_clients[0].Client
,但是当我在我的方法中进行比较时,它会返回false。
答案 0 :(得分:0)
似乎您从多个线程访问_clients。列表与LT; T&GT;不是线程安全的。这可以解释这种奇怪的行为。
答案 1 :(得分:0)
好奇但是为什么要从数组的索引开始,发送WCF代理对象然后再开始在数组中搜索它的索引。似乎更容易和更安全地在索引中作为AsyncState发送,你的问题就消失了。
答案 2 :(得分:0)
如何为IClientAsync实现Equals?
我同意Slashene的说法,它可能与线程有关。 Async回调将在不同的线程上进入。其中每个都在同一个数组上工作,其中一个线程可以从数组中“移除”一个元素,而另一个则在迭代它的一半。
MaxUsers的价值来自哪里?这是连接用户的总数吗?