我刚刚在结构中使用异步方法遇到了一个奇怪的行为.有人可以解释为什么会这样,最重要的是如果有解决方法吗?这是一个简单的测试结构,仅仅是为了演示问题
public struct Structure
{
private int _Value;
public Structure(int iValue)
{
_Value = iValue;
}
public void Change(int iValue)
{
_Value = iValue;
}
public async Task ChangeAsync(int iValue)
{
await Task.Delay(1);
_Value = iValue;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,让我们使用该结构并执行以下调用
var sInstance = new Structure(25);
sInstance.Change(35);
await sInstance.ChangeAsync(45);
Run Code Online (Sandbox Code Playgroud)
第一行实例化结构,sInstance._Value值为25.第二行更新sInstance._Value值,它变为35.现在第三行没有做任何事情,但我希望它能更新sInstance._Value值45而不是sInstance._Value停留35.为什么?有没有办法为结构编写异步方法并更改结构字段的值?
有一个答案简单地解释了路由器如何将来自本地网络的请求转换为外部和后端(https://superuser.com/questions/105838/how-does-router-know-where-to-forward-packet)什么不清楚 - NAT中的记录保存多长时间?
例如,如果我发送UDP请求到25.34.11.56:3874并且我的本地端点是192.168.1.21:54389,则路由器会重写请求数据包并向NAT添加记录.假设外部端点为68.55.32.89:34535.然后,收到我的请求的计算机响应68.55.32.89:34535以及根据NAT记录转发到本地192.168.1.21:54389的数据包.之后会对记录发生什么?
如果25.34.11.56:3874决定在10或100分钟后向我的外部端点68.55.32.89:34535发送请求怎么办?它仍然会被路由器转发到192.168.1.21:54389吗?
假设另一台远程计算机的端点为55.43.77.98:8765.如果此计算机向外部端点68.55.32.89:34535发送请求,会发生什么?它会被转发到本地192.168.1.21:54389还是会被路由器过滤掉,因为远程端点与最初用于第一个请求和NAT记录的25.34.11.56:3874不匹配?
我已经阅读了有关此主题的许多文档,但是有些内容并不清楚。例如,比特种子文档(http://www.bittorrent.org/beps/bep_0005.html)指出
路由表被细分为“存储桶”,每个存储桶覆盖一部分空间。一个空表有一个存储桶,其ID空间范围为min = 0,max = 2 ^ 160。当将ID为“ N”的节点插入表中时,该节点将被放置在最小<= N <最大的存储桶中。空表只有一个存储桶,因此任何节点都必须位于其中。每个存储桶只能容纳K个节点(当前为8个),然后再变为“满”。当存储桶中充满了已知良好的节点时,除非我们自己的节点ID落入存储桶的范围内,否则无法再添加更多节点。在这种情况下,该存储桶将被两个新存储桶替换,每个新存储桶的范围均为旧存储桶的一半,并且旧存储桶中的节点将分布在两个新存储桶中。对于只有一个存储桶的新表,
关于kademlia路由表,它与其他文档有些不同,在kademlia路由表中,根据节点id的位前缀来排列存储桶,但还有另一件令人困惑的事情。当我们回复“查找节点”请求时,我们必须使用XOR操作找到8个最接近所请求节点的节点。我看到一些实现只是通过路由表中的每个项目执行XOR操作,从而找到8个最接近的项目。在我看来,CPU也在浪费。
一切都已经在桶中了。即使我们使用bit torrent文档系统建议的内容,我们也可以更快地找到可能包含所请求节点ID的存储桶,只需枚举存储桶并检查其上的最小和最大数目即可。然后,该存储桶可能应包含关闭节点,但它们是值最接近的节点,而不是异或最相似的XOR最接近的节点(据我所知)。
我使用0到99的数字进行了一个简单的测试,我想找到8个XOR最接近的数字,它们在所寻找的数字附近,但不在附近。现在,考虑一下我们的存储桶,我猜可能存储桶中的所有节点ID都是最接近的,仅是次要异常。因此,例如,如果我们拿这个存储桶,从左边取一个,从右边取一个,并搜索XOR最近的节点ID,我们将找到我们要寻找的东西,并且没有必要遍历路由中的所有节点表。
我是对的还是我错过了什么?
我试图了解 Kademlia 如何寻找资源。现在有很好的描述来构建最接近自身节点的节点树,如何找到节点之间的距离,如何启动该过程等。我不明白的是文件 infohash 如何适合这张图片。所有描述都告诉我们如何进入游戏并构建自己的分布式哈希表部分,但事实并非如此。我们这样做是为了实际查找资源,即具有特定信息哈希的文件。它是如何存储在这个节点树中的还是有一个单独的?如何找到具有此 infohash 的节点,从而获得该文件。
简要提到了这样一个事实,即节点 id 和 infohash 具有相同的 20 字节长度代码,并且节点 id XOR infohash 是节点和资源之间的距离,但我无法想象这是如何以及它如何帮助找到资源?毕竟,实际拥有该资源的节点id可以与该资源具有最大的异或距离。
谢谢你,亚历克斯
首先,我没有找到ObservableBase或AnonymousObservable的自定义实现的好例子.我不知道在我的情况下我需要实施哪一个.情况就是这样.
我使用第三方库,有一个类让我们称它为Producer,它允许我像objProducer.Attach(MyHandler)一样设置一个委托.MyHandler将接收来自制作人的消息.我正在尝试围绕Producer创建一个包装器,使其可观察,理想情况下它是一个独特的类型,而不是只创建一个observable实例(如Observable.Create).
已编辑:第三方制作人具有以下界面
public delegate void ProducerMessageHandler(Message objMessage);
public class Producer : IDisposable {
public void Start();
public void Attach(ProducerMessageHandler fnHandler);
public void Dispose();
}
Run Code Online (Sandbox Code Playgroud)
正如我所提到的,我无法控制它的源代码.它的目的是这样使用:创建一个实例,调用Attach并传递一个委托,调用Start,它基本上在Producer接收或生成它们时,在提供的委托中启动接收消息.
我正在考虑创建公共,class ProducerObservable : ObservableBase<Message>以便当有人订阅它时,我会(Rx库)将消息推送给观察者.看来我需要在我的ProducerObservable的构造函数中调用Attach,然后我需要以某种方式在附加到它的观察者上调用OnNext.这是否意味着我必须对所有这些进行编码:LinkedList<IObserver<Message>>向类中添加观察者列表,然后在ProducerObservable上调用SubscribeCore抽象方法时添加观察者?然后显然我可以枚举LinkedList<IObserver<Message>>MyHandler并为每一个调用OnNext.所有这些看起来都可行,但感觉并不完全正确.我希望.net反应式扩展能够更好地为这种情况做好准备,至少LinkedList<IObserver<Message>>在基类的某个地方实现.
有人可以帮我理解160位(SHA-1)哈希中最重要的字节是什么吗?
我有一个C#代码调用加密库来计算数据流中的哈希码.结果我得到一个20字节的C#数组.然后我从另一个数据流计算另一个哈希码,然后我需要按升序放置哈希码.
现在,我正在努力了解如何比较它们.显然我需要从另一个中减去一个,然后检查结果是否为负,正或零.从技术上讲,我有2个20字节的数组,如果我们从内存角度看一下开头的最低有效字节(较低的内存地址)和最后的最高有效字节(较高的内存地址).另一方面,从人类阅读的角度来看它们,最重要的字节在开头,最不重要的是在结尾,如果我没有弄错,这个顺序用于比较GUID.当然,如果我们使用一种或另一种方法,它将给我们不同的顺序.哪种方式被认为是比较哈希码的正确或传统方式?在我们的情况下,这一点尤为重要,因为我们正在考虑实现一个应该与现有的哈希表兼容的分布式哈希表.
c# ×3
dht ×3
.net ×2
bittorrent ×2
kademlia ×2
async-await ×1
asynchronous ×1
endianness ×1
nat ×1
observable ×1
packet ×1
rewrite ×1
router ×1
routing ×1
sha1 ×1
struct ×1
torrent ×1
udp ×1