我一直在尝试解决这个“并发编程”考试练习(C#):
知道Stream
类包含int Read(byte[] buffer, int offset, int size)
and void Write(byte[] buffer, int offset, int size)
方法,在 C# 中实现NetToFile
复制从接收到的所有数据的方法NetworkStream net
实例到FileStream file
实例。为了进行传输,请使用异步读取和同步写入,避免一个线程在读取操作期间被阻塞。传输结束时net
读操作返回值0。为了简化,不需要支持操作的受控取消。
void NetToFile(NetworkStream net, FileStream file);
我一直在尝试解决这个练习,但我正在努力解决与问题本身相关的问题。但首先,这是我的代码:
public static void NetToFile(NetworkStream net, FileStream file) {
byte[] buffer = new byte[4096]; // buffer with 4 kB dimension
int offset = 0; // read/write offset
int nBytesRead = 0; // number of bytes read on each cycle
IAsyncResult ar;
do {
// read partial content of net (asynchronously)
ar = net.BeginRead(buffer,offset,buffer.Length,null,null);
// wait until read is completed
ar.AsyncWaitHandle.WaitOne();
// get number of bytes read on each cycle
nBytesRead = net.EndRead(ar);
// write partial content to file (synchronously)
fs.Write(buffer,offset,nBytesRead);
// update offset
offset += nBytesRead;
}
while( nBytesRead > 0);
}
我的问题是,在问题陈述中说:
要进行传输,请使用异步
读取和同步写入,避免
一个线程在读取期间被阻塞
运营
我不太确定我的解决方案是否实现了本练习中所需的效果,因为我正在使用AsyncWaitHandle.WaitOne()
等待异步读取完成。
另一方面,我并没有真正弄清楚在这种情况下什么是“非阻塞”解决方案,因为FileStream
write 是要同步进行的......要做到这一点,我必须等到NetworkStream
阅读完成以继续FileStream
写作,不是吗?
你能帮我解决这个问题吗?
[编辑1]Using callback解决方案
好吧,如果我明白的话米切尔·塞勒斯 and willvv回答说,有人建议我使用回调方法将其变成“非阻塞”解决方案。这是我的代码:
byte[] buffer; // buffer
public static void NetToFile(NetworkStream net, FileStream file) {
// buffer with same dimension as file stream data
buffer = new byte[file.Length];
//start asynchronous read
net.BeginRead(buffer,0,buffer.Length,OnEndRead,net);
}
//asynchronous callback
static void OnEndRead(IAsyncResult ar) {
//NetworkStream retrieve
NetworkStream net = (NetworkStream) ar.IAsyncState;
//get number of bytes read
int nBytesRead = net.EndRead(ar);
//write content to file
//... and now, how do I write to FileStream instance without
//having its reference??
//fs.Write(buffer,0,nBytesRead);
}
正如您可能已经注意到的,我被困在回调方法上,因为我没有对FileStream
我想调用“Write(...)”方法的实例。
此外,这不是一个线程安全的解决方案,因为byte[]
字段是公开的并且可以在并发之间共享NetToFile
调用。我不知道如何在不暴露这个问题的情况下解决这个问题byte[]
外部范围中的字段......我几乎可以肯定它可能不会以这种方式暴露。
我不想使用 lambda 或匿名方法解决方案,因为这不在“并发编程”课程的课程内容中。