使用Apache Thrift [https://github.com/apache/thrift]在C#中创建非阻塞服务器时,无法识别以下类/类型:
TNonblockingServerTransport
TNonblockingServer
我想从我的win10笔记本电脑发送命令来控制在高性能服务器(ubuntu)上执行的耗时的计算。这就是为什么我来到Apache Thrift。我已经找到了官方的C#版本教程[https://github.com/apache/thrift/tree/master/tutorial/csharp],并且效果很好。本教程使用所谓的阻止模式(TSimpleServer)。但是在我的情况下,耗时的计算过程应该可以中断。因此,我必须使用非阻塞服务器。
逻辑很简单。对于服务器,我使用了专用标志 forceStop 。如果客户端调用Stop(), forceStop 将设置为true,并且计算循环将中断。
// #Server#
// Server Set-Up
private void SetUp()
{
try
{
CalculatorHandler handler = new CalculatorHandler();
Calculator.Processor processor = new
Calculator.Processor(handler);
var serverTransport = new TServerSocket(9090);
TServer server = new TSimpleServer(processor, serverTransport);
// Use this for a multithreaded server
// server = new TThreadPoolServer(processor, serverTransport);
Console.WriteLine("Starting the server...");
server.Serve();
}
catch (Exception x)
{
Console.WriteLine(x.StackTrace);
}
}
private bool forceStop;
public int TimeConsumingOperation(int n1, int n2)
{
Console.WriteLine("add({0},{1})", n1, n2);
for (int i = 0; i < 10; i++)
{
//calculating
Thread.Sleep(500);
if (forceStop)
{
Quit();
}
}
return n1 + n2;
}
public void Stop()
{
forceStop = true;
}
// Client
// Button#1 Click callback
private void Button_Start_Click()
{
client.TimeConsumingOperation(0,0);
}
// Button#2 Click callback
private void Button_Stop_Click()
{
client.Stop();
}
//
我在Java [https://chamibuddhika.wordpress.com/2011/10/02/apache-thrift-quickstart-tutorial/]中找到了一些有用的示例。我已经尽力将非块服务器的Java代码转换为相应的C#代码,但是我发现C#中似乎没有TNonblockingServerTransport。有人可以帮助我解决这个问题吗?
// Java Code
public class NonblockingServer {
private void start() {
try {
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(7911);
ArithmeticService.Processor processor = new ArithmeticService.Processor(new ArithmeticServiceImpl());
TServer server = new TNonblockingServer(new TNonblockingServer.Args(serverTransport).
processor(processor));
System.out.println("Starting server on port 7911 ...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
NonblockingServer srv = new NonblockingServer();
srv.start();
}
}
答案 0 :(得分:0)
这个问题实际上有两个答案。
首先,您的设置存在缺陷。
// #Server#
// Server Set-Up
private bool forceStop;
public void Stop()
{
forceStop = true;
}
假设我们有两个客户,两个都开始新的计算。现在,一个客户想要中止。会发生什么?
解决方案将以一种结构化的方式进行构造,其中计算是一个独立的业务逻辑对象,该对象在TimeConsumingOperation()
上实例化,并通过某种方式(通常通过返回某种ID)供客户端使用。 / p>
当客户端现在想要中止时,它将调用Stop(calcualtionID)
。现在,服务器端逻辑会将调用路由到实现,并触发任何终止机制,而C#可能是CancellationToken
。
一旦计算完成,将需要第三次调用来从服务器端查询最终结果。请注意,我们仍然使用TSimpleServer
,它之所以起作用,是因为我们避免通过API设计来阻止调用。
是的,尚无C#的实现。由于Thrift是开源的,所以这很可能意味着到目前为止,没有人遇到该用例,并且想花时间在实现上。这并不是说这种用例可能不存在。
存在的是
Task.Run(() => { your code })
这可能有助于解决您的用例。另外,当与ASP.NET一起使用时,由于运行时已经为多个连接提供了足够的支持,因此不需要无阻塞服务器。
有一些方法可以解决您遇到的限制。可以通过将现有的(例如Java)非阻塞实现之一移植到become a contributor来NetStd(首选,因为C#和NetCore将在下一个发行版中成熟为“已弃用”状态,并且两者都将成为最终被NetStd取代)