不同的线程访问的MemoryStream [英] different thread accessing MemoryStream

查看:477
本文介绍了不同的线程访问的MemoryStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一点code这将数据写入到MemoryStream对象直接进入它的数据缓冲区通过调用的GetBuffer()。它还使用和更新中的地位和SetLength()性能适当。

There's a bit of code which writes data to a MemoryStream object directly into it's data buffer by calling GetBuffer(). It also uses and updates the Position and SetLength() properties appropriately.

这code正常工作99.9999%的时间。从字面上看。只有每个这么多的100000的重复就会BARF的。具体问题是,MemoryStream中的位置属性突然返回零,而不是适当的值。

This code works properly 99.9999% of the time. Literally. Only every so many 100,000's of iterations it will barf. The specific problem is that the Position property of MemoryStream suddenly returns zero instead of the appropriate value.

不过,code的补充,为0检查并抛出一个异常,其中包括日志喜欢的位置和长度在一个单独的方法将MemoryStream属性。那些返回正确的值。另外除了同样的方法在记录显示,当这种罕见的情况发生时,该位只有零点这个特殊的方法中。

However, code was added that checks for the 0 and throws an exception which includes log of the MemoryStream properties like Position and Length in a separate method. Those return the correct value. Further addition of logging within the same method shows that when this rare condition occurs, the Position only has zero inside this particular method.

好。显然,这必须是一个线程问题。而最有可能的一个编译器优化的问题。

Okay. Obviously, this must be a threading issue. And most likely a compiler optimization issue.

不过,这个软件的本质是它的举办的任务以调度和几个实际的O / S线程,所以任何一个可以运行此code,在任何给定的时间 - 但从来没有超过一个在时间

However, the nature of this software is that it's organized by "tasks" with a scheduler and so any one of several actual O/S thread may run this code at any give time--but never more than one at a time.

所以这是我的猜测,通常恰巧在同一个线程不断得到使用这种方法,然后在一个难得的机会,在不同的线程习惯。 (只需code的想法通过捕捉和比较线程ID为验证这一理论。)

So it's my guess that ordinarily it so happens that the same thread keeps getting used for this method and then on a rare occasion a different thread get used. (Just code the idea to test this theory by capturing and comparing the thread id.)

然后由于编译器的优化,在不同的线程永远不会得到正确的值。它得到一个过时的价值。

Then due to compiler optimizations, the different thread never gets the correct value. It gets a "stale" value.

通常在这样的情况下我会申请一个动荡关键字有关的变量,看能否解决。但在这种情况下,变量是将MemoryStream对象内。

Ordinarily in a situation like this I would apply a "volatile" keyword to the variable in question to see if that fixes it. But in this case the variables are inside the MemoryStream object.

没有人有任何其他的想法?或者,这是否意味着我们要实现我们自己的MemoryStream对象?

Does anyone have any other idea? Or does this mean we have to implement our own MemoryStream object?

真诚的, 韦恩

编辑:只是跑了试验,计数调用此方法的总数目和计数的次数的ManagedThreadId比最后呼叫不同。这几乎正​​好50%,它的线程切换的时候 - 他们之间的交流。所以上面我的理论是,几乎肯定是错误的或会更经常发生的错误。

Just ran a test which counts the total number of calls to this method and counts the number of times the ManagedThreadId is different than the last call. It's almost exactly 50% of the time that it switches threads--alternating between them. So my theory above is almost certainly wrong or the error would occur far more often.

编辑:出现此错误的所以很少,这将需要近一个星期之前,感觉它真的走了什么信心没有错误运行。相反,它是更好地运行实验,以确认precisely了问题的本质。

This bug occurs so rarely that it would take nearly a week to run without the bug before feeling any confidence it's really gone. Instead, it's better to run experiments to confirm precisely the nature of the problem.

编辑:在每个使用的MemoryStream的5种方法。锁定当前通过锁定处理()语句

Locking currently is handled via lock() statements in each of 5 methods that use the MemoryStream.

推荐答案

(真正需要榜样code证实了这一点。)

(Really need exemplar code to confirm this.)

的MemoryStream 成员不会记录为线程安全的(如的 位置 ),所以你需要确保你只能访问这个实例(或任何引用一个对象逻辑的一部分 MemoryStream的)从一个线程的时间。

MemoryStream members are not documented as thread safe (e.g. Position) so you need to ensure you are only access this instance (or any reference to an object logically a part of the MemoryStream) from one thread at a time.

的MemoryStream 终止的不是的记载为具有线程关联,这样你就可以从不同的线程&mdash访问实例;只要这样的访问是不是并发的。

But MemoryStream is not documented as having thread affinity, so you can access an instance from a different thread—as long as such an access is not concurrent.

线程是硬(不言自明这个Q&安培; A)。

Threading is hard (axiomatic for this Q&A).

我会建议你有一定的并发访问回事,有两个线程同时访问同一个实例,这是偶然,破坏实例状态的某些方面。

I would suggest you have some concurrent access going on, with two threads both accessing the same instance concurrently and this is, occasionally, corrupting some aspect of the instance state.

我会确保我把锁尽可能简单(试图要格外聪明,并限制锁往往是非常困难的原因找到的bug),并把事情的工作。在一个多核心系统测试也可能有帮助。只有尝试和优化锁定,如果分析显示有潜在的(作为一个整体的应用程序)的增益显著网。

I would ensure I keep the locking as simple as possible (trying to be extra clever and limiting locking is often a cause of very hard to find bugs) and get things working. Testing on a multi-core system may also help. Only try and optimise the locking if profiling shows there is potential for significant net (application as a whole) gain.

这篇关于不同的线程访问的MemoryStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆