我只是想理解C#中的管道。我有一个简单的LinqPad脚本:
void Main() => Program.Main(null);
// You can define other methods, fields, classes and namespaces here
class Program
{
public static void Main(string[] args)
{
StartServer();
Task.Delay(1000).Wait();
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
client.Connect();
while (true)
{
string input = Guid.NewGuid().ToString();
if (String.IsNullOrEmpty(input)) break;
var someBuffer = new byte[4];
client.Write(someBuffer, 0, someBuffer.Length);
"Client 1st Write".Dump();
client.Write(someBuffer, 0, someBuffer.Length);
"Client 2nd Write".Dump();
client.Read(someBuffer, 0, someBuffer.Length);
"Client 1st Read".Dump();
}
}
static void StartServer()
{
Task.Factory.StartNew(() =>
{
var server = new NamedPipeServerStream("PipesOfPiece");
server.WaitForConnection();
var someBuffer = new byte[4];
while (true)
{
server.Read(someBuffer, 0, someBuffer.Length);
"Server 1st Read".Dump();
server.Write(someBuffer, 0, someBuffer.Length);
"Server 1st Write".Dump();
}
});
}
}
如果运行上面的代码,将得到以下输出:
Client 1st Write
Server 1st Read
因此对client.write
的第二次调用将永远阻塞。有人能解释一下为什么第二次调用write(在同一线程中)会导致管道阻塞吗?
THX
其根本原因是根据同步化上下文和线程切换阻塞问题。像这样做伙计:
public static async Task Main(string[] args)
{
StartServer();
await Task.Delay(1000);
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
await client.ConnectAsync();
while (true)
{
string input = Guid.NewGuid().ToString();
if (String.IsNullOrEmpty(input)) break;
var someBuffer = new byte[4];
await client.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 1st Write");
await client.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 2nd Write");
await client.ReadAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 1st Read");
//await Task.Delay(100);
}
}
static void StartServer()
{
Task.Factory.StartNew(async () =>
{
var server = new NamedPipeServerStream("PipesOfPiece");
await server.WaitForConnectionAsync();
var someBuffer = new byte[4];
while (true)
{
await server.ReadAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Server 1st Read");
await server.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Server 1st Write");
}
});
}
问题内容: 我想知道在Python应用程序中导入包的首选方法。我有一个这样的包结构: project.app1.views进口project.app1.models和project.app2.models。我想到有两种方法可以做到这一点。 绝对进口: 或具有明确的相对导入,如在Python 2.5中使用PEP 328引入的那样: 什么是最pythonic的方式做到这一点? 问题答案: 绝对进口。从
问题内容: 我们目前正在编写一个应用程序,该应用程序分为多个项目/模块。例如,让我们采用以下模块: myApp-DAO myApp-jabber 每个模块都有其自己的Spring上下文xml文件。对于DAO模块,我有一个PropertyPlaceholderConfigurer,它读取带有必需的数据库连接参数的属性文件。在jabber模块中,我还有一个用于jabber连接属性的PropertyPl
问题内容: 我已经开始学习线程同步。 同步方法: 同步块: 什么时候应该使用方法和块? 为什么块比方法更好? 问题答案: 这不是更好的问题,只是有所不同。 同步方法时,实际上是在与对象本身进行同步。对于静态方法,您正在同步到对象的类。因此,以下两段代码以相同的方式执行: 就像您写的一样。 如果要控制到特定对象的同步,或者只想将方法的 一部分 同步到该对象,则指定一个块。如果在方法声明上使用关键字,
问题内容: 我想知道使用像这样的构造是否可靠: 我是否有可能因为初始化块将在初始化块之前执行? (关于我为什么不在上层init的末尾进行初始化。块:只是味道问题;如果所描述的构造不可靠,我将这样做) 问题答案: 是的,保证静态初始化程序块按文本顺序执行。 从JLS,第12.4.1节: 目的是类或接口类型具有一组初始化器,这些初始化器将其置于一致状态,并且该状态是其他类观察到的第一个状态。 静态初始
问题内容: 我知道如何按字节读取文件,但是找不到如何按字节读取文件的示例。我有一个字节数组,我想读取512bytes的文件并通过套接字发送它们。 我尝试读取文件的总字节,然后减去512字节,直到得到小于512字节的块,并发出EOF和传输结束的信号。 我正在尝试实现TFTP,其中以512字节块发送数据。 无论如何,我们将为一个例子而感激。 问题答案: 您…一次读取512个字节。
问题内容: 不得不与Guice打交道,我想知道我应该如何处理模块方面的依赖关系。 在Guice中,每个模块都是由实例提供的。因此,如果我有一个需要某种服务的模块,它将创建一个向该服务添加绑定的模块并进行安装(binder.install(module))。 现在,我有两个独立的模块,完全可以独立使用,并且都安装了相同的数据库模块。 单独使用两个模块都不会出现问题,但是如果两个模块在同一应用程序中使