Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.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# 使用线程(任务)执行包含I/O的工作_C#_Multithreading_Io_Task - Fatal编程技术网

C# 使用线程(任务)执行包含I/O的工作

C# 使用线程(任务)执行包含I/O的工作,c#,multithreading,io,task,C#,Multithreading,Io,Task,我需要从一个文件中读取数据,处理并将结果写入另一个文件。我使用backgroundworker来显示进程状态。我写了类似这样的东西来在backgroundworker的DoWork事件中使用 private void ProcData(string fileToRead,string fileToWrite) { byte[] buffer = new byte[4 * 1024]; //fileToRead & file

我需要从一个文件中读取数据,处理并将结果写入另一个文件。我使用backgroundworker来显示进程状态。我写了类似这样的东西来在backgroundworker的DoWork事件中使用

private void ProcData(string fileToRead,string fileToWrite)
        {
            byte[] buffer = new byte[4 * 1024];

            //fileToRead & fileToWrite have same size
            FileInfo fileInfo = new FileInfo(fileToRead);

            using (FileStream streamReader = new FileStream(fileToRead, FileMode.Open))
            using (BinaryReader binaryReader = new BinaryReader(streamReader))
            using (FileStream streamWriter = new FileStream(fileToWrite, FileMode.Open))
            using (BinaryWriter binaryWriter = new BinaryWriter(streamWriter))
            {
                while (streamWriter.Position < fileInfo.Length)
                {
                    if (streamWriter.Position + buffer.Length > fileInfo.Length)
                    {
                        buffer = new byte[fileInfo.Length - streamWriter.Position];
                    }

                    //read
                    buffer = binaryReader.ReadBytes(buffer.Length);

                    //proccess
                    Proc(buffer);

                    //write
                    binaryWriter.Write(buffer);

                    //report if procentage changed
                    //...

                }//while
            }//using
        }
private void ProcData(字符串fileToRead,字符串fileToWrite)
{
字节[]缓冲区=新字节[4*1024];
//fileToRead和fileToWrite的大小相同
FileInfo FileInfo=newfileinfo(fileToRead);
使用(FileStream streamReader=newfilestream(fileToRead,FileMode.Open))
使用(BinaryReader BinaryReader=新的BinaryReader(streamReader))
使用(FileStream streamWriter=newfilestream(fileToWrite,FileMode.Open))
使用(BinaryWriter BinaryWriter=新的BinaryWriter(streamWriter))
{
while(streamWriter.PositionfileInfo.Length)
{
buffer=新字节[fileInfo.Length-streamWriter.Position];
}
//阅读
buffer=binaryReader.ReadBytes(buffer.Length);
//过程
Proc(缓冲区);
//写
写入(缓冲区);
//如果程序更改,请报告
//...
}//当
}//使用
}
但它比仅仅从fileToRead读取和写入fileToWrite要慢5倍,所以我考虑线程。我在网站上读到了一些问题,并尝试了类似的方法

private void ProcData2(字符串fileToRead,字符串fileToWrite)
{
int threadNumber=4;//例如
任务[]任务=新任务[threadNumber];
long[]startByte=新长[threadNumber];
long[]长度=新的long[threadNumber];
//将文件分割为螺纹编号(4)零件
//并更新startByte和length
var parentTask=Task.Run(()=>
{
对于(int i=0;i
{
Proc2(文件读取、文件写入、起始字节[i],长度[i]);
});
}
});
parentTask.Wait();
Task.WaitAll(任务);
}
//
私有void Proc2(字符串fileToRead、字符串fileToWrite、长fileStartByte、长partLength)
{ 
字节[]缓冲区=新字节[4*1024];
使用(FileStream streamReader=newfilestream(fileToRead,FileMode.Open,FileAccess.Read,FileShare.Read))
使用(BinaryReader BinaryReader=新的BinaryReader(streamReader))
使用(FileStream streamWriter=newfilestream(fileToWrite,FileMode.Open,FileAccess.Write,FileShare.Write))
使用(BinaryWriter BinaryWriter=新的BinaryWriter(streamWriter))
{
Seek(fileStartByte,SeekOrigin.Begin);
Seek(fileStartByte,SeekOrigin.Begin);
while(streamWriter.PositionfileStartByte+partLength)
{
buffer=新字节[fileStartByte+partLength-streamWriter.Position];
}
//阅读
buffer=binaryReader.ReadBytes(buffer.Length);
//过程
Proc(缓冲区);
//写
写入(缓冲区);
//如果程序更改,请报告
//...
}//当
}//使用
}
但我认为它有一些问题,每次切换任务时,它都需要再次寻找。我考虑读取文件,对Proc()使用线程,然后写入结果,但这似乎是错误的。如何正确执行?(从文件中读取缓冲区,使用任务处理并将其写入其他文件)

//===================================================================

根据皮特·柯克汉姆邮报,我修改了我的方法。我不知道为什么,但它对我不起作用。我添加了新的方法,以帮助他们。谢谢大家

 private void ProcData3(string fileToRead, string fileToWrite)
        {
            int bufferSize = 4 * 1024;
            int threadNumber = 4;//example
            List<byte[]> bufferPool = new List<byte[]>();
            Task[] tasks = new Task[threadNumber];

            //fileToRead & fileToWrite have same size
            FileInfo fileInfo = new FileInfo(fileToRead);

            using (FileStream streamReader = new FileStream(fileToRead, FileMode.Open))
            using (BinaryReader binaryReader = new BinaryReader(streamReader))
            using (FileStream streamWriter = new FileStream(fileToWrite, FileMode.Open))
            using (BinaryWriter binaryWriter = new BinaryWriter(streamWriter))
            {
                while (streamWriter.Position < fileInfo.Length)
                {
                    //read
                    for (int g = 0; g < threadNumber; g++)
                    {
                        if (streamWriter.Position + bufferSize <= fileInfo.Length)
                        {
                            bufferPool.Add(binaryReader.ReadBytes(bufferSize));
                        }
                        else
                        {
                            bufferPool.Add(binaryReader.ReadBytes((int)(fileInfo.Length - streamWriter.Position)));
                            break;
                        }
                    }

                    //do
                    var parentTask = Task.Run(() =>
                    {
                        for (int th = 0; th < bufferPool.Count; th++)
                        {
                            int index = th;

                            //threads
                            tasks[index] = Task.Factory.StartNew(() =>
                            {
                                Proc(bufferPool[index]);
                            });

                        }//for th
                    });

                    //stop parent task(run childs)
                    parentTask.Wait();

                    //wait till all task be done
                    Task.WaitAll(tasks);

                    //write
                    for (int g = 0; g < bufferPool.Count; g++)
                    {
                        binaryWriter.Write(bufferPool[g]);
                    }

                    //report if procentage changed
                    //...

                }//while
            }//using
        }
private void ProcData3(字符串fileToRead,字符串fileToWrite)
{
int bufferSize=4*1024;
int threadNumber=4;//示例
List bufferPool=新列表();
任务[]任务=新任务[threadNumber];
//fileToRead和fileToWrite的大小相同
FileInfo FileInfo=newfileinfo(fileToRead);
使用(FileStream streamReader=newfilestream(fileToRead,FileMode.Open))
使用(BinaryReader BinaryReader=新的BinaryReader(streamReader))
使用(FileStream streamWriter=newfilestream(fileToWrite,FileMode.Open))
使用(BinaryWriter BinaryWriter=新的BinaryWriter(streamWriter))
{
while(streamWriter.Position
{
Proc(缓冲池[索引]);
});
}//为了
});
//停止父任务(运行子任务)
parentTask.Wait();
//等到所有任务完成
 private void ProcData3(string fileToRead, string fileToWrite)
        {
            int bufferSize = 4 * 1024;
            int threadNumber = 4;//example
            List<byte[]> bufferPool = new List<byte[]>();
            Task[] tasks = new Task[threadNumber];

            //fileToRead & fileToWrite have same size
            FileInfo fileInfo = new FileInfo(fileToRead);

            using (FileStream streamReader = new FileStream(fileToRead, FileMode.Open))
            using (BinaryReader binaryReader = new BinaryReader(streamReader))
            using (FileStream streamWriter = new FileStream(fileToWrite, FileMode.Open))
            using (BinaryWriter binaryWriter = new BinaryWriter(streamWriter))
            {
                while (streamWriter.Position < fileInfo.Length)
                {
                    //read
                    for (int g = 0; g < threadNumber; g++)
                    {
                        if (streamWriter.Position + bufferSize <= fileInfo.Length)
                        {
                            bufferPool.Add(binaryReader.ReadBytes(bufferSize));
                        }
                        else
                        {
                            bufferPool.Add(binaryReader.ReadBytes((int)(fileInfo.Length - streamWriter.Position)));
                            break;
                        }
                    }

                    //do
                    var parentTask = Task.Run(() =>
                    {
                        for (int th = 0; th < bufferPool.Count; th++)
                        {
                            int index = th;

                            //threads
                            tasks[index] = Task.Factory.StartNew(() =>
                            {
                                Proc(bufferPool[index]);
                            });

                        }//for th
                    });

                    //stop parent task(run childs)
                    parentTask.Wait();

                    //wait till all task be done
                    Task.WaitAll(tasks);

                    //write
                    for (int g = 0; g < bufferPool.Count; g++)
                    {
                        binaryWriter.Write(bufferPool[g]);
                    }

                    //report if procentage changed
                    //...

                }//while
            }//using
        }