Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ConcurrentDictionary无法找到密钥,即使我确信它存在_C#_String_Multithreading_Stream_Concurrentdictionary - Fatal编程技术网

C# ConcurrentDictionary无法找到密钥,即使我确信它存在

C# ConcurrentDictionary无法找到密钥,即使我确信它存在,c#,string,multithreading,stream,concurrentdictionary,C#,String,Multithreading,Stream,Concurrentdictionary,在我的静态类中,我有以下内容: static var cache = new ConcurrentDictionary<string, object>(); 线程#1后几秒钟,在线程#2中: 它输出“这不存在:abc” 然后在线程#2之后的线程#3几秒钟内: 我得到输出“string:abc”和“是的,它存在” 在线程#1中,我使用MD5创建字符串,如下所示: Convert.ToBase64String (md5.ComputeHash(Encoding.ASCII.GetByt

在我的静态类中,我有以下内容:

static var cache = new ConcurrentDictionary<string, object>();
线程#1后几秒钟,在线程#2中:

它输出“这不存在:abc”

然后在线程#2之后的线程#3几秒钟内:

我得到输出“string:abc”和“是的,它存在”

在线程#1中,我使用MD5创建字符串,如下所示:

Convert.ToBase64String (md5.ComputeHash(Encoding.ASCII.GetBytes(value)))
string data = System.Web.HttpUtility.UrlEncode(theString);
byte[] buffer = Encoding.UTF8.GetBytes (data);
NetworkStream stream = client.GetStream(); // TcpClient client;
stream.Write (buffer, 0, buffer.Length);
string data = "";
NetworkStream stream = client.GetStream(); // TcpClient client;
byte[] bytes = new byte[4096];
do {   
    int i = stream.Read (bytes, 0, bytes.Length);
    data += Encoding.UTF8.GetString (bytes, 0, i);
} while(stream.DataAvailable);
string theString = HttpUtility.UrlDecode(data);
在线程#2中,我从字节流中获取字符串,在字节流中使用UTF8编码写入字符串,然后再次使用UTF8编码从字节读取字符串

在线程3中,我通过循环ConcurrentDictionary获取字符串

我错过了什么?就我所知,线程2应该像线程3一样工作

我有两种可能性,在我看来,这两种可能性都很遥远:

  • 这是我不知道的某种同步问题吗
  • 还是字符串有什么不同?当我将它输出到控制台时,它没有区别
有人有其他想法或解决方案吗

编辑:

我将数据写入流,如下所示:

Convert.ToBase64String (md5.ComputeHash(Encoding.ASCII.GetBytes(value)))
string data = System.Web.HttpUtility.UrlEncode(theString);
byte[] buffer = Encoding.UTF8.GetBytes (data);
NetworkStream stream = client.GetStream(); // TcpClient client;
stream.Write (buffer, 0, buffer.Length);
string data = "";
NetworkStream stream = client.GetStream(); // TcpClient client;
byte[] bytes = new byte[4096];
do {   
    int i = stream.Read (bytes, 0, bytes.Length);
    data += Encoding.UTF8.GetString (bytes, 0, i);
} while(stream.DataAvailable);
string theString = HttpUtility.UrlDecode(data);
然后我从流中读取数据,如下所示:

Convert.ToBase64String (md5.ComputeHash(Encoding.ASCII.GetBytes(value)))
string data = System.Web.HttpUtility.UrlEncode(theString);
byte[] buffer = Encoding.UTF8.GetBytes (data);
NetworkStream stream = client.GetStream(); // TcpClient client;
stream.Write (buffer, 0, buffer.Length);
string data = "";
NetworkStream stream = client.GetStream(); // TcpClient client;
byte[] bytes = new byte[4096];
do {   
    int i = stream.Read (bytes, 0, bytes.Length);
    data += Encoding.UTF8.GetString (bytes, 0, i);
} while(stream.DataAvailable);
string theString = HttpUtility.UrlDecode(data);

如果要将字节写入网络流,然后将其读回,则必须在数据前面加上一个表示后面有多少字节的值,或者需要一个数据结束标记。按照编写代码的方式,很可能接收代码只提取了部分数据

例如,假设您的密钥是“HelloWorld”。您的发送代码将发送字符串。接收代码在缓冲区中看到“Hello”部分,抓取它,检查是否有更多数据可用,这不是因为网络传输线程尚未将其复制到缓冲区

所以你只能得到一部分字符串

另一个可能发生的事情是你读得太多。如果您向网络流写入两个字符串,并且您的读者将它们都当作单个字符串来读取,则可能会发生这种情况

要正确操作,您应该执行以下任一操作:

int dataLength = buffer.Length;
byte[] lengthBuff = BitConverter.GetBytes(dataLength);
stream.Write(lengthBuff, 0, lengthBuff.Length);  // write length
stream.Write(buffer, 0, buffer.Length);  // write data
然后通过先读取长度,然后从流中读取那么多字节来读取它

或者,您可以使用数据结束标记:

stream.Write(buffer, 0, buffer.Length);  // write data
buffer[0] = end_of_data_byte;
stream.Write(buffer, 0, 1);  // write end of data
读卡器读取字节,直到得到数据标记的结尾

数据结束标记使用什么取决于您。它应该是正常数据流中不存在的东西


就个人而言,我会选择长度前缀。

如果要将字节写入网络流,然后再将其读回,则必须在数据前面加上一个表示后面有多少字节的值,或者需要一个数据结束标记。按照编写代码的方式,很可能接收代码只提取了部分数据

例如,假设您的密钥是“HelloWorld”。您的发送代码将发送字符串。接收代码在缓冲区中看到“Hello”部分,抓取它,检查是否有更多数据可用,这不是因为网络传输线程尚未将其复制到缓冲区

所以你只能得到一部分字符串

另一个可能发生的事情是你读得太多。如果您向网络流写入两个字符串,并且您的读者将它们都当作单个字符串来读取,则可能会发生这种情况

要正确操作,您应该执行以下任一操作:

int dataLength = buffer.Length;
byte[] lengthBuff = BitConverter.GetBytes(dataLength);
stream.Write(lengthBuff, 0, lengthBuff.Length);  // write length
stream.Write(buffer, 0, buffer.Length);  // write data
然后通过先读取长度,然后从流中读取那么多字节来读取它

或者,您可以使用数据结束标记:

stream.Write(buffer, 0, buffer.Length);  // write data
buffer[0] = end_of_data_byte;
stream.Write(buffer, 0, 1);  // write end of data
读卡器读取字节,直到得到数据标记的结尾

数据结束标记使用什么取决于您。它应该是正常数据流中不存在的东西


就我个人而言,我会选择长度前缀。

很难理解您的问题流程-但是我注意到一件事:在网络写入()之后是否刷新()?否则,您可能会在写入过程中出现延迟,这通常会导致与时间相关的问题。

很难理解您的问题流程-但是我注意到一件事:在网络写入()之后是否刷新()?否则,您可能会在写入过程中出现延迟,这通常会导致与时间相关的问题。

您必须提供更多的代码。您希望看到什么?最小的代码片段,其行为如所述。我在其中添加了“编辑”,其中描述了如何将字符串写入流并读回。当您将其输出到控制台时,输出长度并在字符串周围加引号。听起来可能有一些空格或不可打印的字符。类似于
Console.WriteLine(“这不存在:'{0}',Length={1}',stringfromsomether,stringfromsomether.Length)您必须提供更多代码。您希望看到什么?最小的代码段,其行为如所述。我在其中添加了“编辑”,描述如何将字符串写入流并将其读回。当您将其输出到控制台时,输出长度并在字符串周围加上引号。听起来可能有一些空格或不可打印的字符。类似于
Console.WriteLine(“这不存在:'{0}',Length={1}',stringfromsomether,stringfromsomether.Length)谢谢你的回答。我理解这个概念,但它并不能真正解决问题。当我从线程#2中的流中获取数据并将其传递给静态类以确定键是否存在时,它表示键不存在,但仍输出正确的字符串,如问题说明所示。此外,我可能过于简化了从流中读取的过程。我实际上读取了很多数据(但不到4kb),并使用正则表达式从文本数据中解析出字符串。谢谢您的回答。我理解这个概念,但它并不能真正解决问题。当我从线程#2中的流中获取数据并将其传递给静态类以确定该键是否存在时,它表示该键不存在,但仍然输出正确的字符串,如解释中所示