可以说,JNPF快速开发平台适用于任何行业系统,企业不必烦恼底层架构设计,低代码开发的可视化界面和拖拉拽的应用搭建方式快速赋能开发者和业务人员,可短时间开发出如ERP、OA、CRM、HR、MIS以及电信、银行、政府、企业等各行业的企业应用系统。
平台功能包含了表单、流程、数据的开发与应用,将企业的需求全部囊括在平台里。抽象和封装的代码降低开发人员的代码准入门槛,契合中小 企业应用开发灵活性需求,推进中小企业数字化进程。
在数字化的“新赛道”,企业应发挥低代码优势, 帮助自身实现产业线高效管理和层级数据集成,助力企业提升效益,紧跟技术革新步伐,保持市场优势。最近的JNPF3.3升级,是对整个NPF系统的一次全方位的优化 整体提升了JNPF的普适性,功能开发范围更广了,适用企业类型更加丰富。
// Added to the previous benchmark
[Benchmark]
public async Task EnumerateNew()
{
var request = new HttpRequestMessage(HttpMethod.Get, s_uri);
using var resp = await s_client.SendAsync(request, default);
foreach (var header in resp.Headers.NonValidated) { }
foreach (var contentHeader in resp.Content.Headers.NonValidated) { }
await resp.Content.CopyToAsync(Stream.Null);
}
![](https://i-blog.csdnimg.cn/blog_migrate/bcb5126fa40ae5a27192763bffb4e585.png)
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
ReadOnlyMemory<byte> dataToSend;
using (var hc = new HttpClient())
{
dataToSend = await hc.GetByteArrayAsync("https://www.gutenberg.org/cache/epub/3200/pg3200.txt");
}
Memory<byte> receiveBuffer = new byte[dataToSend.Length];
foreach (bool compressed in new[] { false, true })
{
using var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
listener.Listen();
using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(listener.LocalEndPoint);
using Socket server = listener.Accept();
using var clientStream = new PassthroughTrackingStream(new NetworkStream(client, ownsSocket: true));
using var clientWS = WebSocket.CreateFromStream(clientStream, new WebSocketCreationOptions { IsServer = false, DangerousDeflateOptions = compressed ? new WebSocketDeflateOptions() : null });
using var serverWS = WebSocket.CreateFromStream(new NetworkStream(server, ownsSocket: true), new WebSocketCreationOptions { IsServer = true, DangerousDeflateOptions = compressed ? new WebSocketDeflateOptions() : null });
var sw = new Stopwatch();
for (int trial = 0; trial < 5; trial++)
{
long before = clientStream.BytesRead;
sw.Restart();
await serverWS.SendAsync(dataToSend, WebSocketMessageType.Binary, true, default);
while (!(await clientWS.ReceiveAsync(receiveBuffer, default)).EndOfMessage) ;
sw.Stop();
Console.WriteLine($"Compressed: {compressed,5} Bytes: {clientStream.BytesRead - before,10:N0} Time: {sw.ElapsedMilliseconds:N0}ms");
}
}
sealed class PassthroughTrackingStream : Stream
{
private readonly Stream _stream;
public long BytesRead;
public PassthroughTrackingStream(Stream stream) => _stream = stream;
public override bool CanWrite => true;
public override bool CanRead => true;
public override async ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken)
{
int n = await _stream.ReadAsync(buffer, cancellationToken);
BytesRead += n;
return n;
}
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) =>
_stream.WriteAsync(buffer, cancellationToken);
protected override void Dispose(bool disposing) => _stream.Dispose();
public override bool CanSeek => false;
public override long Length => throw new NotSupportedException();
public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
public override void SetLength(long value) => throw new NotSupportedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}