替代StreamReader.Peek和了Thread.interrupt [英] Alternative to StreamReader.Peek and Thread.Interrupt

查看:170
本文介绍了替代StreamReader.Peek和了Thread.interrupt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的什么,我试图做快速序言。我想启动一个进程并启动两个线程监视stderr和标准输入。每个线程嚼断流的位,然后触发它到的NetworkStream。如果有错误在任一线程,两个线程需要立即死亡。

Quick preface of what I'm trying to do. I want to start a process and start up two threads to monitor the stderr and stdin. Each thread chews off bits of the stream and then fires it out to a NetworkStream. If there is an error in either thread, both threads need to die immediately.

这些流程与标准输出和标准输入监控线程中的每一个由一个主服务器进程中剥离出来。这就会变得相当复杂的原因是因为有很容易被40或这些过程50在任何给定的时间。只有在早上阵阵重启都曾经有过超过50个连接,但它确实需要能够处理100以上。我测试用100个并发连接

Each of these processes with stdout and stdin monitoring threads are spun off by a main server process. The reason this becomes tricky is because there can easily be 40 or 50 of these processes at any given time. Only during morning restart bursts are there ever more than 50 connections, but it really needs to be able to handle 100 or more. I test with 100 simultaneous connections.

try
{
    StreamReader reader = this.myProcess.StandardOutput;

    char[] buffer = new char[4096];
    byte[] data;
    int read;

    while (reader.Peek() > -1 ) // This can block before stream is streamed to
    {
        read = reader.Read(buffer, 0, 4096);
        data = Server.ClientEncoding.GetBytes(buffer, 0, read);
        this.clientStream.Write(data, 0, data.Length); //ClientStream is a NetworkStream
    }
}
catch (Exception err)
{
        Utilities.ConsoleOut(string.Format("StdOut err for client {0} -- {1}", this.clientID, err));
        this.ShutdownClient(true);
}

此代码块在一个线程是现在没有后台运行。有类似螺纹的StandardError的流。因为是单声道的问题导致这些事件虽然看起来现在是固定的,我喜欢这种方法可以确保我在阅读和写作的一切并不总是正确的,甚至解雇我使用这种方法,而不是听OutputDataReceived和ErrorDataReceived的顺序。

This code block is run in one Thread which is right now not Background. There is a similar thread for the StandardError stream. I am using this method instead of listening to OutputDataReceived and ErrorDataReceived because there was an issue in Mono that caused these events to not always fire properly and even though it appears to be fixed now I like that this method ensures I'm reading and writing everything sequentially.

ShutdownClient与真只是试图杀死两个线程。不幸的是,我发现,使这项工作的唯一方法是对stdErrThread和stdOutThread对象使用一个中断。理想的情况下偷看不会阻止,我可以只使用一个手动重置事件保持检查的标准输出或标准输入新数据,然后当事件被翻转刚刚死了。

ShutdownClient with True simply tries to kill both threads. Unfortunately the only way I have found to make this work is to use an interrupt on the stdErrThread and stdOutThread objects. Ideally peek would not block and I could just use a manual reset event to keep checking for new data on stdOut or stdIn and then just die when the event is flipped.

我无疑这是做到这一点的最好办法。有没有不使用中断来执行这个办法吗?

I doubt this is the best way to do it. Is there a way to execute this without using an Interrupt?

我想改变,因为我只是在我的日志,我错过了里面Utlities.ConsoleOut抛出ThreadInterruptException看到的。这只是做了System.Console.Write如果一个静态变量是真实的,但我的地方想这块

I'd like to change, because I just saw in my logs that I missed a ThreadInterruptException thrown inside Utlities.ConsoleOut. This just does a System.Console.Write if a static variable is true, but I guess this blocks somewhere.

编辑:

这些线程是由服务器根据请求发起集体父线程的一部分。因此,我不能设置输出和错误线程的背景和杀死应用。我可以杀了从主服务器父线程,但是这同样会得到粘性与皮克阻挡。

These threads are part of a parent Thread that is launched en masse by a server upon a request. Therefore I cannot set the StdOut and StdErr threads to background and kill the application. I could kill the parent thread from the main server, but this again would get sticky with Peek blocking.

这个是一个服务器增加了信息。

Added info about this being a server.

另外,我开始意识到对查询可能是最终的解决方案,更好的排队方法。

Also I'm starting to realize a better Queuing method for queries might be the ultimate solution.

推荐答案

我可以告诉这整个混乱的事实,皮克茎块。你真的试图解决一些在框架根本打破,这是不容易的(即不是一个肮脏的黑客)。就个人而言,我会解决这个问题的根源,这是阻断皮克。单就已经按照微软的实现,因此同样的问题结束了。

I can tell this whole mess stems from the fact that Peek blocks. You're really trying to fix something that is fundamentally broken in the framework and that is never easy (i.e. not a dirty hack). Personally, I would fix the root of the problem, which is the blocking Peek. Mono would've followed Microsoft's implementation and thus ends up with the same problem.

虽然我知道如何解决这个问题,我应该被允许改变框架的源代码,解决方法是冗长和费时。

While I know exactly how to fix the problem should I be allowed to change the framework source code, the workaround is lengthy and time consuming.

但在这里不用。

从本质上讲,微软需要做的为改变 Process.StartWithCreateProcess ,使得 standardOutput StandardError的是既赋予一种特殊类型的的StreamReader (如 PipeStreamReader )。

Essentially, what Microsoft needs to do is change Process.StartWithCreateProcess such that standardOutput and standardError are both assigned a specialised type of StreamReader (e.g. PipeStreamReader).

在此 PipeStreamReader ,他们需要同时重写 ReadBuffer 过载(即需要在两个重载更改为虚拟的的StreamReader 第一),使得读取之前, PeekNamedPipe 被称为做实际的偷看。由于它的那一刻, FileStream.Read()(由叫做皮克())将阻止在管道中读取当没有数据可用于读取。虽然 FileStream.Read() 0字节效果很好的文件,它不会在管道上工作那么好。事实上,.NET队无缘管文件的重要组成部分 - 的 PeekNamedPipe WinAPI的

In this PipeStreamReader, they need to override both ReadBuffer overloads (i.e. need to change both overloads to virtual in StreamReader first) such that prior to a read, PeekNamedPipe is called to do the actual peek. As it is at the moment, FileStream.Read() (called by Peek()) will block on pipe reads when no data is available for read. While a FileStream.Read() with 0 bytes works well on files, it doesn't work all that well on pipes. In fact, the .NET team missed an important part of the pipe documentation - PeekNamedPipe WinAPI.

PeekNamedPipe功能类似于但下列情况除外ReadFile函数:

The PeekNamedPipe function is similar to the ReadFile function with the following exceptions:

...

函数总是立即返回一个单线程应用程序, 连如果在管道中没有数据即可。命名管道句柄(阻塞或非阻塞)等待模式对功能没有影响。

The function always returns immediately in a single-threaded application, even if there is no data in the pipe. The wait mode of a named pipe handle (blocking or nonblocking) has no effect on the function.

在这个时刻的最好的事情,而不这个问题的解决框架将推出自己的Process类(约WinAPI的瘦包装就足够了)。

The best thing at this moment without this issue solved in the framework would be to roll out your own Process class (a thin wrapper around WinAPI would suffice).

这篇关于替代StreamReader.Peek和了Thread.interrupt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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