質問

I have an array of files that are having write operations performed on them, I'm using a Parallel.ForEach loop to speed this up.

The problem is that when I have more than one thread, it behaves erratically. The program makes 10 writes of 250000 random bytes to WAV files, this will result in periods of about 1.3 seconds of static. What is happening is that with multiple threads, in the vast majority of files, there isn't any static, Windows indicates the files have changed, but the audio content has not, the other problem is that some clips had about 6 minutes of static written to it, which is impossible, the code only writes 2500000 bytes (~10.3 seconds) to each file, so for some reason its writing bytes to the wrong files, so some have no static, others have an absurd amount. Its impossible to miss the static, so it can't be me. I know something is going wrong.

Everything worked fine before I multithreaded the program, so I used MaxDegreeofParallelism = 1 and everything worked fine, so I know the problem is being caused by multiple threads.

Parallel.ForEach(files, new ParallelOptions{MaxDegreeOfParallelism = 4}, file =>
{
Random rand = new Random();
using (stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite))
{
FileInfo info = new FileInfo(file);
for (int i = 0; i < 10; i++)
{
    int pos = rand.Next(5000000, Convert.ToInt32(info.Length));
    for (int x = 0; x < 250000; x++)
    {
        byte number = array[rand.Next(array.Length)];
        stream.Seek(pos, SeekOrigin.Begin);
        pos += 4;
        stream.WriteByte(number);
    }
}
}
});

EDIT: The other problem is that with multiple threads it writes to the header portion, which contains the critical data, so no media player recognizes the format. This only happens with multiple threads, and I'm ignoring the first 5 million bytes, which I know is enough.

EDIT:2 Updated code.

Can anyone shed some light on what it is about multiple threads that causes my code to not function correctly?

役に立ちましたか?

解決

stream is declared outside of the delegate being executed by Parallel.ForEach. All the threads created by Parallel.ForEach are trying to use the same variable. Since there's no locking, it's undefined what value of stream each thread will have - you're probably seeing several threads writing to the same stream, which is resulting in your weird multi-threaded behavior.

Try removing the declaration of stream outside of the delegate, and changing

using (stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite))

to

using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite))

他のヒント

Random number generator is not thread-safe. Jon Skeet has a good article on this and how to make a thread-safe random number generator.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top