RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-212981

Andrei Khotko's questions

Martin Hope
Andrei Khotko
Asked: 2022-06-17 17:42:47 +0000 UTC

C# 在单个 try-catch 中包装对各种类方法的调用

  • 1

一个抽象的例子。我有一个具有以下界面的客户端:

public interface IUserClient
{
    Task<IUser> GetUserByIdAsync(int id);
    Task<IUser> FindUserByFirstNameAndLastNameAsync(string firstName, string lastName);
    Task<IUser> CreateUserAsync(string firstName, string lastName, string phone);
}

public interface IUser
{
    int Id { get; }
    string FirstName { get; set; }
    string LastName { get; set; }
    string Phone { get; set; }
}

我需要围绕这个客户端编写一个包装器,如果客户端方法抛出某个Exception. 到目前为止,我已经实现了这样的东西:

public class UserClientWrapper : IUserClient
{
    private readonly IUserClient _userClient;

    public UserClientWrapper(IUserClient userClient)
    {
        _userClient = userClient;
    }

    public async Task<IUser> GetUserByIdAsync(int id)
    {
        try
        {
            return await _userClient.GetUserByIdAsync(id);
        }
        catch (UnauthorizedAccessException)
        {
            // Пытаемся перелогиниться

            try
            {
                return await _userClient.GetUserByIdAsync(id);
            }
            catch (UnauthorizedAccessException)
            {
                // Пишем в лог, что что-то не так, и пробрасываем выше этот exception
                throw;
            }
        }
    }

    public async Task<IUser> FindUserByFirstNameAndLastNameAsync(string firstName, string lastName)
    {
        try
        {
            return await _userClient.FindUserByFirstNameAndLastNameAsync(firstName, lastName);
        }
        catch (UnauthorizedAccessException)
        {
            // Пытаемся перелогиниться

            try
            {
                return await _userClient.FindUserByFirstNameAndLastNameAsync(firstName, lastName);
            }
            catch (UnauthorizedAccessException)
            {
                // Пишем в лог, что что-то не так, и пробрасываем выше этот exception
                throw;
            }
        }
    }

    public async Task<IUser> CreateUserAsync(string firstName, string lastName, string phone)
    {
        // и тут тоже самое
    }
}

但令我困惑的是,我不得不在每个方法中复制代码try-catch。我想把这个逻辑放在一个单独的方法中,但我不知道这是否可能。因此,问题来了:在这种情况下如何避免代码重复?

PS重要!客户端方法不同,具有不同的签名和返回类型,但它们都是异步的。

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-04-23 15:45:11 +0000 UTC

谁可以通过 TCP/IP 发送这个数据包,为什么?

  • 3

有一个我写的部署服务(通过域名公开可用),它接受 TCP/IP 连接并处理某种格式的数据包。今天,一个奇怪的客户端连接到这个服务,它以大约 2 分 50 秒的时间间隔发送了包含以下内容的数据包:

SSH-2.0-libssh2_1.8.0

我的服务自然会丢弃此类数据包并引发错误。

问:可能是什么?试图通过 SSH 连接到机器?你需要做些什么吗?


在浏览器中访问这个“奇怪客户端”的 IP 地址会打开默认页面Apache2 Debian Default Page。

безопасность
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-04-13 17:15:31 +0000 UTC

PostgreSQL。如何从大表中删除所有数据?

  • 0

有一张桌子(我们称之为logs)。它已经积累了33GB的记录。它需要清理干净。试图做

DELETE FROM logs

但是运行命令一段时间后,输出显示第N(数量很大)行数被删除了,但表的大小保持不变(我想行数也没有改变)。这是我第一次遇到这个问题,我不知道该怎么办。

实际上,一个问题:如何从表中删除所有数据logs?


该表只有一个主键,没有索引。

база-данных
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-02-24 22:22:13 +0000 UTC

实体框架/SQL Server。根据 Id 数组选择数据集合,其中每个条目都是唯一的并匹配条件

  • 0

我有一个 ItemHistory表

 -----------------------------------
| Id | ItemId | DateTimeUtc         |
|-----------------------------------|
| 1  | 1      | 2021-01-01 00:00:00 |
|----|------------------------------|
| 2  | 2      | 2021-01-01 00:00:00 |
|----|------------------------------|
| 3  | 2      | 2021-01-01 12:50:00 |
|----|------------------------------|
| 4  | 1      | 2021-01-02 17:00:00 |
|----|------------------------------|
| 5  | 3      | 2021-02-24 16:59:00 |
|----|------------------------------|
|... |...     | ...                 |
------------------------------------

有必要实现一个数据获取,它需要一个集合ItemId和 time dateTimeUtc,并将及时返回Item每个最接近的条目(即,使差异Abs(DateTimeUtc - dateTimeUtc)最小)。据我了解,您需要对数据进行分组,ItemId并在每个组中排序,Math.Abs((x.DateTimeUtc - dateTimeUtc).TotalMilliseconds然后从每个组中选择第一条记录。我可怜的尝试做某事:

var result = context.Set<ItemHistory>()
    .Where(x => itemIds.Contains(x.VehicleId))
    .GroupBy(x => x.ItemId)
    .OrderBy(x => Math.Abs((x.DateTimeUtc - dateTimeUtc).TotalMilliseconds))
    .ToList();

但这当然不能编译(OrderBy行有错误)。在分组中,他并不强,原则上在 EntityFramework 中。因此,我寻求帮助。

我接受 c# 和 sql 中的答案

PS问题的标题很难表述。


实体框架版本:

<package id="EntityFramework" version="6.1.2" targetFramework="net45" />
c#
  • 2 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-02-12 19:55:51 +0000 UTC

是否可以在 Visual Studio 中为具有多个 TargetFrameworks 的项目指定当前的 TargetFramework?

  • 2

应该为不同版本的框架构建一个项目。这是 csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net45;</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
    <PackageReference Include="Some.HttpClient" Version="1.0.0" />
  </ItemGroup>

  <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
    <Reference Include="System.Net.Http" />
  </ItemGroup>

</Project>

对于这样一个项目,我只对 进行语法高亮.net standard 2.0,而对于net 4.5它,它根本没有经过验证。这是来自 Visual Studio 的屏幕截图:

在此处输入图像描述

问题:有什么方法可以切换net45到检查 VisualStudio 中的编译错误以进行构建net45?

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-02-08 20:36:09 +0000 UTC

在 MS SQL 中查找两个相邻行之间的日期差异

  • 0

有SQL Server 11。大概有下表Statuses

------------------------------------
| Id | DateTimeUtc         | Status |
------------------------------------
| 1  | 2020-02-08 15:23:00 | Moving |
| 2  | 2020-02-08 15:26:00 | Moving |
| 3  | 2020-02-08 15:29:00 | Moving |
| 4  | 2020-02-08 15:39:00 | Moving |
| 5  | 2020-02-08 15:43:00 | Moving |
| ...                               |
------------------------------------

如何选择Id与之前状态相差超过 3 分钟的记录?我期待这样的事情:

SELECT Id
FROM Statuses
WHERE DATEDIFF(MINUTE, [current].DateTimeUtc, [prev].DateTimeUtc) > 3
ORDER BY DateTimeUtc

有很多数据,所以最好使用省时的查询。根据我的发现,有 functions LAG / LEAD,但它们不在版本 11 中。

база-данных
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2022-01-16 20:26:04 +0000 UTC

为 ASP.NET Core 3.1 设置 IIS UrlRewrite 时出现问题

  • 2

将旧的 c 项目迁移asp net core 2.2到asp net core 3.1. 用作前端Angular。.net core 2.2这是连接IIS 的 UrlRewrite 规则的工作代码。类代码Startup:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    //...

    app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    
    app.UseAuthentication();
    ConfigureUrlRewriting(app, env);
    ConfigureRouting(app);
}

private static void ConfigureUrlRewriting(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment() && File.Exists("IISUrlRewrite.xml"))
    {
        using (var reader = File.OpenText("IISUrlRewrite.xml"))
        {
            var options = new RewriteOptions().AddIISUrlRewrite(reader);
            app.UseRewriter(options);
        }
    }
}

private static void ConfigureRouting(IApplicationBuilder app)
{
    app.UseDefaultFiles(new DefaultFilesOptions
    {
        DefaultFileNames = new List<string> { "index.html" }
    });
    app.UseStaticFiles();
    app.UseMvc(routes =>
    {
        routes.MapRoute(name: "default", template: "api/{controller}/{id}");
    });
}

从微软迁移到.net core 3.1指南后,代码并没有太大变化:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...

    app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    
    app.UseAuthentication();
    ConfigureUrlRewriting(app, env);
    ConfigureRouting(app);
}


private static void ConfigureUrlRewriting(IApplicationBuilder app, IHostEnvironment env)
{
    if (env.IsDevelopment() && File.Exists("IISUrlRewrite.xml"))
    {
        using (var reader = File.OpenText("IISUrlRewrite.xml"))
        {
            var options = new RewriteOptions().AddIISUrlRewrite(reader);
            app.UseRewriter(options);
        }
    }
}

private static void ConfigureRouting(IApplicationBuilder app)
{
    app.UseDefaultFiles(new DefaultFilesOptions
    {
        DefaultFileNames = new List<string> { "index.html" }
    });
    app.UseStaticFiles();

    // Изменилось только то, что ниже
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(name: "default", pattern: "api/{controller}/{id}");
    });
}

浏览器返回文件index.html,但由于某种原因未找到所有静态文件。而是返回index.html。这是证明:

静态文件作为索引 html

从微软的 UrlRewrite 文档中可以清楚地看出,中间件AddRewriter(rewriter)必须在之前添加AddStaticFiles()。我不明白 .net 核心中可能发生了什么变化,这样一系列添加中间件可能会停止按预期工作。有什么问题?我已经坐了两天了,一直在努力解决这个问题。也许其他 IIS 模块用于 .net core 3.1 并且 xml 语法发生了变化?

以防万一,我将添加文件的内容IISUrlRewrite.xml:

<rewrite>
  <rules>
    <rule name="AngularJS Routes" stopProcessing="true">
      <match url=".*" />
      <conditions logicalGrouping="MatchAll">
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <add input="{REQUEST_URI}" pattern="^/(api)/" negate="true" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>
c#
  • 2 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2021-11-03 21:19:25 +0000 UTC

BackgroundService 无法正常终止

  • 2

无法弄清楚为什么我的BackgroundService(.NET Core 3.1)无法正常关闭。

编写了一个服务,它应该监听一个 tcp 端口并处理某种格式的消息。写了以下内容BackgroundService:

internal sealed class TcpListenerBackgroundService : BackgroundService
{
    private readonly ITcpPortListener _tcpPortListener;
    private readonly ILogger<TcpListenerBackgroundService> _logger;

    public TcpListenerBackgroundService(ITcpPortListener tcpListener, ILogger<TcpListenerBackgroundService> logger)
    {
        _tcpPortListener = tcpListener;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            await _tcpPortListener.ListenAsync(stoppingToken);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unexpected error was occured");
        }
    }
}

ITcpPortListener此处注入以下内容TcpPortListener:

public sealed class TcpPortListener : ITcpPortListener
{
    private readonly ILogger<TcpPortListener> _logger;
    private readonly IPacketProcessor _packetProcessor;
    private readonly TcpListener _listener;
    private TaskCompletionSource<object> _appTerminationSource;

    public TcpPortListener(
        ITcpPortListenerConfiguration config,
        IPacketProcessor packetProcessor,
        ILogger<TcpPortListener> logger)
    {
        _listener = new TcpListener(IPAddress.Any, config.PortNumber);
        _packetProcessor = packetProcessor;
        _logger = logger;
    }

    public async Task ListenAsync(CancellationToken stoppingToken)
    {
        _appTerminationSource = new TaskCompletionSource<object>();
        await using (stoppingToken.Register(_appTerminationSource.SetCanceled))
        {
            var taskList = new List<Task>();
            _listener.Start();

            while (!stoppingToken.IsCancellationRequested)
            {
                var acceptClientTask = _listener.AcceptTcpClientAsync();
                await Task.WhenAny(acceptClientTask, _appTerminationSource.Task);

                if (acceptClientTask.IsCompletedSuccessfully)
                {
                    var client = acceptClientTask.Result;
                    var processTask = ProcessClientAsync(client, stoppingToken);

                    taskList.Add(processTask);
                }

                taskList.RemoveAll(p => p.IsCompleted);
            }

            _logger.LogInformation("Waiting for all clients termination...");
            await Task.WhenAll(taskList.ToArray());

            _logger.LogInformation("Terminate listening...");
            _listener.Stop();
            _logger.LogInformation("Listening was terminated successfully!");
        }
    }

    private async Task ProcessClientAsync(TcpClient client, CancellationToken stoppingToken)
    {
        var clientIp = GetClientIp(client);
        _logger.LogInformation($"Client[{clientIp}]. Connected");

        try
        {
            var stream = client.GetStream();
            var socket = client.Client;

            _logger.LogInformation($"Client[{clientIp}]. Start processing");

            var buffer = new byte[1024];
            var packetContainer = new SuntechPacketContainer();
            var isSocketConnected = CheckSocketConnection(socket);

            while (isSocketConnected && !stoppingToken.IsCancellationRequested)
            {
                var readTask = stream.ReadAsync(buffer, 0, buffer.Length, stoppingToken);
                await Task.WhenAny(readTask, _appTerminationSource.Task);

                if (readTask.IsCompletedSuccessfully)
                {
                    var bytesRead = readTask.Result;
                    if (bytesRead == 0)
                    {
                        isSocketConnected = false;
                        break;
                    }

                    packetContainer.Append(buffer.Take(bytesRead));
                    var packets = packetContainer.FetchFullPackets();
                    await ProcessPacketsAsync(packets);

                    isSocketConnected = CheckSocketConnection(socket);
                }
            }

            if (!isSocketConnected)
            {
                _logger.LogInformation($"Client[{clientIp}]. Socket disconnected. The message processing for the client has been stopped");
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Client[{clientIp}]. Unexpected error was occured during client processing");
        }
        finally
        {
            _logger.LogInformation($"Client[{clientIp}]. Closing the client connection");
            client.Close();
        }
    }

    private static string GetClientIp(TcpClient client)
    {
        return ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
    }

    private async Task ProcessPacketsAsync(IEnumerable<byte[]> packets)
    {
        foreach (var packet in packets)
        {
            await _packetProcessor.ProcessPacketAsync(packet);
        }
    }

    private static bool CheckSocketConnection(Socket socket)
    {
        const int connectionTimeoutInMicroseconds = 1_000;

        var poll = socket.Poll(connectionTimeoutInMicroseconds, SelectMode.SelectRead);
        return !((poll && (socket.Available == 0)) || !socket.Connected);
    }
}

在 CentOS 7 上使用systemd.

问题是有时候(我不知道具体是在什么情况下),如果至少有一个客户端连接到服务,而那一刻我想停止服务(调用service stop),那么服务将无限期结束并systemd挂起,因此我不得不将其杀死,之后,在了解服务的状态后,我会被告知该进程由于等待超时到期而被杀死。我完全不明白为什么会发生这种情况,因为该方法ListenAsync是根据日志得出的。这绝对不是因为该方法需要ListenAsync很长时间才能完成。我附上一个示例日志:

//...
2020-11-03 04:01:22.299 -05:00 [INF] Application is shutting down...
2020-11-03 04:01:22.333 -05:00 [INF] Client[127.0.0.1]. Closing the client connection
2020-11-03 04:01:22.334 -05:00 [INF] Waiting for all clients termination...
2020-11-03 04:01:22.335 -05:00 [INF] Terminate listening...
2020-11-03 04:01:22.336 -05:00 [INF] Listening was terminated successfully!

有一种感觉,在某些情况下并非所有资源都被释放。请检查我的代码是否存在资源管理可能不准确的地方。我的眼睛已经起泡了,什么也看不见。

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2021-10-23 18:14:44 +0000 UTC

任务在什么情况下被销毁?

  • 2

一个抽象的例子:有一个_reader,它异步读取数据。有一个 ,当应用程序退出时cancellationToken将变为:Cancel

while (!cancellationToken.IsCancellationRequested)
{
    var readingTask = _reader.ReadAsync();
    await Task.WhenAny(readingTask, Task.Delay(Timeout.Infinite, cancellationToken));
    
    if (readingTask.IsCompletedSuccessfully)
    {
        var readResult = readingTask.Result;
        // Обрабатываем readResult
    }
}

假设循环已经执行了 40 次,会不会因为循环的每次迭代都会创建一个Task.Delay(Timeout.Infinite, cancellationToken)只有在 token 为 时才会完成的任务而导致内存被污染或性能下降Cancel?或者垃圾收集器(或其他人)会破坏这些无休止的任务吗?

c#
  • 2 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2021-10-21 17:36:36 +0000 UTC

如何在单独的线程上运行异步方法而不等待它执行?

  • 3

有一个方法:

public async Task StartListeningAsync(CancellationToken stoppingToken)
{
    _listener.Start();

    while (!stoppingToken.IsCancellationRequested)
    {
        var client = await _listener.AcceptTcpClientAsync();
        var thread = new Thread(async () => await ProcessClientAsync(client, stoppingToken));
        thread.Start();
    }
}

这_listener是标准类的对象TcpListener。任务是在单独的线程中处理单独的客户端。客户端处理可能需要很长时间才能断开连接(例如 5 天)。客户端处理方法ProcessClientAsync是异步的(原则上可以同步)。我需要在单独的线程上运行此方法。目前我通过new Thread. 有人告诉我,在await方法内部的第一个之后,ProcessClientAsync线程会将控制权返回给外部,导致处理线程终止(这在此处进行了讨论)。

还有另一种选择Task.Run:

_listener.Start();

while (!stoppingToken.IsCancellationRequested)
{
    var client = await _listener.AcceptTcpClientAsync();
    Task.Run(() => ProcessClientAsync(client, stoppingToken), stoppingToken);
}

但是编译器会警告这个选项:

警告 CS4014 由于不等待此调用,因此在调用完成之前继续执行当前方法。考虑将“等待”运算符应用于调用结果。

问题:ProcessClientAsync在我的情况下,在单独的线程中运行客户端处理方法如何正确?该方法最好保持异步。如果不能保持异步,请解释原因。

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2021-10-20 18:52:28 +0000 UTC

如何在 CancellationToken 条件下正确终止预期任务的执行?

  • 1

有.NET Core Hosted Service一个(后台工作人员)应用程序会无限期地运行,直到它被禁用。

标准的 .NET Core 抽象类接口BackgroundService提供了一个Task ExecuteAsync(CancellationToken stoppingToken). 我已经实现了这样的:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    try
    {
        _listener.Start(); // _listener инициализируется в конструкторе

        while (!stoppingToken.IsCancellationRequested)
        {
            var client = await _listener.AcceptTcpClientAsync();
            var thread = new Thread(async () => await ProcessClientAsync(client, stoppingToken));
            thread.Start();
        }
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Unexpected error was occured");
    }
}

当应用程序终止时,这个stoppingToken变成Cancelled. 问题是如果您await _listener.AcceptTcpClientAsync();在等待时关闭应用程序,它将崩溃并出现以下错误:

System.OperationCanceledException: '操作已取消。'

此外,这个错误是在方法之外抛出的ExecuteAsync。据我了解,这是因为当前线程仍在等待完成await _listener.AcceptTcpClientAsync();,但它并没有终止。

问题:如何包装方法调用await _listener.AcceptTcpClientAsync();,使其等待由条件完成stoppingToken.IsCancellationRequested?因此,例如,如果stoppingToken.IsCancellationRequested == true,则将引发某种类型的异常(例如,OperationCancelledException)

我看到了这样的包装,但我不确定它有多正确:

public static async Task<T> WithWaitCancellation<T>(
    this Task<T> task, CancellationToken cancellationToken)
{
    // The tasck completion source. 
    var tcs = new TaskCompletionSource<bool>();

    // Register with the cancellation token.
    using (cancellationToken.Register(
            s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
        // If the task waited on is the cancellation token...
        if (task != await Task.WhenAny(task, tcs.Task))
            throw new OperationCanceledException(cancellationToken);

    // Wait for one or the other to complete.
    return await task;
}
c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2021-10-15 20:17:40 +0000 UTC

如何在 Ubuntu 上测试与 MS SQL 数据库的连接?

  • 0

您需要在远程 Ubuntu 机器 (Ubuntu 18.04) 上检查与 MS SQL 数据库的连接。据我了解,我需要一个可以提供给的 MS SQL 客户端,ConnectionString然后它会说它是否能够连接。Ubuntu上有这样的客户端吗?

到目前为止,我还没有在网上找到它。我为 mysql找到了这样一个客户端,但我不知道它是否可以与 MS SQL 连接(我猜不是)

ubuntu
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-09-16 00:26:35 +0000 UTC

C#。如何正确编写从一种抽象类型到另一种抽象类型的转换?

  • 2

前言。为了以某种方式描述问题,我编写了一个控制台应用程序(参见下面的代码)。

问题的本质。假设有两个消息传递协议:St和Gv. 有两种抽象类型:

  • 消息
  • 消息

需要实现类型消息StMessage到GvMessage. 实现StMessage包含一组唯一的消息类型字段。转换后,您需要在控制台中显示一条消息。

这就是我所做的。代码很多,为了方便分区域,最好在代码编辑器中查看。代码:

using System;

namespace TestHelloWorld.ConsoleApp
{
    internal static class Program
    {
        private static void Main(string[] args)
        {
            LaunchTestOfStatusMessageConverting();
            LaunchTestOfSpeedMessageConverting();
        }

        private static void LaunchTestOfStatusMessageConverting()
        {
            var stMessage = new StMessageStatus
            {
                Status = "Pending"
            };

            var converter = GetConverterForMessage(stMessage);
            var gvMessage = converter.Convert(stMessage);

            var printer = new ConsoleMessagePrinter();
            printer.PrintMessage(gvMessage);
        }

        private static void LaunchTestOfSpeedMessageConverting()
        {
            var stMessage = new StMessageSpeed
            {
                Speed = 42
            };

            var converter = GetConverterForMessage(stMessage);
            var gvMessage = converter.Convert(stMessage);

            var printer = new ConsoleMessagePrinter();
            printer.PrintMessage(gvMessage);
        }

        private static IMessageConverter GetConverterForMessage(StMessage stMessage)
        {
            switch (stMessage.MessageType)
            {
                case StMessageType.Speed:
                    return new SpeedMessageConverter();
                case StMessageType.Status:
                    return new StatusMessageConverter();
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }

    #region [ GvMessages ]

    public enum GvMessageType
    {
        Speed,
        Status
    }

    public abstract class GvMessage
    {
        public abstract GvMessageType MessageType { get; }
    }

    public class GvMessageSpeed : GvMessage
    {
        public override GvMessageType MessageType => GvMessageType.Speed;

        public int Speed { get; set; }
    }

    public class GvMessageStatus : GvMessage
    {
        public override GvMessageType MessageType => GvMessageType.Status;

        public string Status { get; set; }
    }

    #endregion


    #region [ StMessages ]
    
    public enum StMessageType
    {
        Speed,
        Status
    }

    public abstract class StMessage
    {
        public abstract StMessageType MessageType { get; }
    }

    public class StMessageSpeed : StMessage
    {
        public override StMessageType MessageType => StMessageType.Speed;

        public int Speed { get; set; }
    }

    public class StMessageStatus : StMessage
    {
        public override StMessageType MessageType => StMessageType.Status;

        public string Status { get; set; }
    }

    #endregion


    #region [ Converters ]

    public interface IMessageConverter
    {
        GvMessage Convert(StMessage stMessage);
    }

    public class StatusMessageConverter : IMessageConverter
    {
        public GvMessage Convert(StMessage stMessage)
        {
            var stMessageStatus = stMessage as StMessageStatus;
            if (stMessageStatus == null)
            {
                throw new ArgumentException($"Message is not of {nameof(StMessageStatus)} type", nameof(stMessage));
            }

            var gvMessageStatus = new GvMessageStatus
            {
                Status = stMessageStatus.Status
            };

            return gvMessageStatus;
        }
    }

    public class SpeedMessageConverter : IMessageConverter
    {
        public GvMessage Convert(StMessage stMessage)
        {
            var stMessageSpeed = stMessage as StMessageSpeed;
            if (stMessageSpeed == null)
            {
                throw new ArgumentException($"Message is not of {nameof(StMessageStatus)} type", nameof(stMessage));
            }

            var gvMessageSpeed = new GvMessageSpeed
            {
                Speed = stMessageSpeed.Speed
            };

            return gvMessageSpeed;
        }
    }

    #endregion


    #region [ Message printers ]

    public interface IMessagePrinter
    {
        void PrintMessage(GvMessage message);
    }

    public class ConsoleMessagePrinter : IMessagePrinter
    {
        public void PrintMessage(GvMessage message)
        {
            string messageAsText;
            switch (message.MessageType)
            {
                case GvMessageType.Speed:
                    var speedMessage = (GvMessageSpeed) message;
                    messageAsText = $"Gv speed message. Speed={speedMessage.Speed}";
                    break;
                case GvMessageType.Status:
                    var statusMessage = (GvMessageStatus)message;
                    messageAsText = $"Gv status message. Status={statusMessage.Status}";
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            Console.WriteLine(messageAsText);
        }
    }

    #endregion
}

我无法理解我使用 C# 语言工具如何正确地解决了这个问题。我认为这里有问题。至少,我不喜欢对象从基本类型到具体类型的逆转换。

请检查我解决此问题的方法,如果有问题,请提供您自己的解决方案。

c#
  • 2 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-09-09 16:31:14 +0000 UTC

.NET 中的 TCP 协议保证

  • 1

有一个问题困扰着我。有一个 GPS 跟踪器,它使用自己的协议通过 TCP / IP 传输数据。我正在编写一个后台服务(.NET Core 3.1),它应该侦听 tcp 端口并将消息包以原始形式(字节 [] 或编码为字符串)保存到数据库中。现在我的 tcp 端口嗅探代码如下所示:

public class TcpListenerBackgroundService : BackgroundService
{
    private readonly ITcpListenerWrapper _tcpListener;
    private readonly ILogger<TcpListenerBackgroundService> _logger;

    public TcpListenerBackgroundService(ITcpListenerWrapper tcpListener, ILogger<TcpListenerBackgroundService> logger)
    {
        _tcpListener = tcpListener;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await _tcpListener.StartListeningAsync(stoppingToken);
    }
}

TcpListenerWrapper.cs

public sealed class TcpListenerWrapper : ITcpListenerWrapper, IDisposable
{
    private const int BufferSize = 1024;

    private readonly TcpListener _listener;
    private readonly IMessageManager _messageManager;

    public TcpListenerWrapper(ITcpListenerWrapperConfiguration config, IMessageManager messageManager)
    {
        _listener = new TcpListener(IPAddress.Any, config.PortNumber);
        _messageManager = messageManager;
    }

    public async Task StartListeningAsync(CancellationToken stoppingToken)
    {
        _listener.Start();

        while (!stoppingToken.IsCancellationRequested)
        {
            var client = await _listener.AcceptTcpClientAsync();
            var stream = client.GetStream();

            while (!stoppingToken.IsCancellationRequested)
            {
                var buffer = new byte[BufferSize];

                using (var ms = new MemoryStream())
                {
                    int numBytesRead;
                    while ((numBytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, numBytesRead);
                    }

                    if (ms.Length > 0)
                    {
                        var messageAsText = Encoding.ASCII.GetString(buffer);
                        // Console.WriteLine($"New message received: {messageAsText}");

                        var message = _messageManager.CreateMessage(buffer);
                        message.Save(); // Сохранение в бд.
                    }
                }
            }
        }
    }

    public void Dispose()
    {
        _listener.Stop();
    }
}

让 GPS 追踪器以 1 分钟的周期发送 10 个数据包。

问题:是否有可能NetworkStream一次有多个包(比如 3 个包)?或者有保证他们会一次来一个吗?

添加。问题:消息监听代码是否有错误?也许这里缺少一些东西,或者反之亦然,太多了?

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-09-02 15:09:30 +0000 UTC

Tcp转储。如何查看进入特定端口的流量?

  • 0

有一个通过 TCP / IP 运行的地理数据传输设备的模拟器。该模拟器位于远程服务器上,通过 Internet(使用 ip + 端口)将数据发送到特定机器。客户说他会设置模拟器,以便它可以在特定端口上向我们的服务器发送消息。我需要以某种方式查看是否有一些流量通过此端口。

服务器在 CentOS 上运行。系统管理员说他给外面开了一个端口,扔到了这台机器上。我正在尝试使用 tcpdump。我输入命令:

# tcpdump port 9000

我在控制台中看到的内容:

tcpdump:未实现 NFLOG 链路层类型过滤

请告诉我需要做什么来确定特定端口号上是否有流量。系统管理不强。

centos
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-07-16 18:32:28 +0000 UTC

编写单元测试时如何避免 InternalsVisibleTo ?

  • 1

我正在尝试通过测试来涵盖以下课程:

public sealed class VdiRunHistoryDataManager : IVdiRunHistoryDataManager
{
    private const string InvalidValueErrorMessage = "Invalid value";

    private readonly IDbConnectionWrapper _connection;

    public VdiRunHistoryDataManager(IDbConnectionWrapper connection)
    {
        _connection = connection;
    }

    public DateTime GetVdiLastRunDateTime(string vdiRunTypeCode, string vdiRunScopeCode, int operatorId)
    {
        if (!IsValidVdiRunTypeCode(vdiRunTypeCode))
        {
            throw new ArgumentException(InvalidValueErrorMessage, nameof(vdiRunTypeCode));
        }

        if (!IsValidVdiRunScopeCode(vdiRunScopeCode))
        {
            throw new ArgumentException(InvalidValueErrorMessage, nameof(vdiRunScopeCode));
        }

        var vdiRunScope = GetVdiRunScopeByCode(vdiRunScopeCode);
        var vdiRunType = GetVdiRunTypeByCode(vdiRunTypeCode);
        var vdiRunHistory = FindVdiRunHistory(operatorId, vdiRunType.Id, vdiRunScope.Id);

        var longTimeAgo = DateTime.UtcNow.AddYears(-100);
        var lastRun = vdiRunHistory?.LastRun ?? longTimeAgo;
        return lastRun;
    }

    public void SaveVdiRunHistory(VdiRunHistoryDataModel historyDataModel)
    {
        if (historyDataModel == null)
        {
            throw new ArgumentNullException(nameof(historyDataModel));
        }

        if (!IsValidVdiRunTypeCode(historyDataModel.VdiRunTypeCode))
        {
            throw new ArgumentException(InvalidValueErrorMessage, nameof(historyDataModel.VdiRunTypeCode));
        }

        if (!IsValidVdiRunScopeCode(historyDataModel.VdiRunScopeCode))
        {
            throw new ArgumentException(InvalidValueErrorMessage, nameof(historyDataModel.VdiRunScopeCode));
        }

        var vdiRunType = GetVdiRunTypeByCode(historyDataModel.VdiRunTypeCode);
        var vdiRunScope = GetVdiRunScopeByCode(historyDataModel.VdiRunScopeCode);
        var historyInternalModel = FindVdiRunHistory(historyDataModel.OperatorId, vdiRunType.Id, vdiRunScope.Id) ??
                                   CreateVdiRunHistoryInternalModel(historyDataModel.OperatorId, vdiRunType.Id,
                                       vdiRunScope.Id);

        historyInternalModel.LastRun = historyDataModel.LastRun;

        _connection.Save(historyInternalModel);
    }

    private VdiRunScopeLookupInternalDataModel GetVdiRunScopeByCode(string code)
    {
        var runScope = _connection.SingleOrDefault<VdiRunScopeLookupInternalDataModel>(p => p.Code == code);
        ThrowInvalidOperationExceptionIfNull(runScope, CreateNotFoundErrorMessage("VDIRunScope", code));

        return runScope;
    }

    private VdiRunTypeLookupInternalDataModel GetVdiRunTypeByCode(string code)
    {
        var runType = _connection.SingleOrDefault<VdiRunTypeLookupInternalDataModel>(p => p.Code == code);
        ThrowInvalidOperationExceptionIfNull(runType, CreateNotFoundErrorMessage("VDIRunType", code));

        return runType;
    }

    [AssertionMethod]
    private static void ThrowInvalidOperationExceptionIfNull<T>(T instance, string exceptionMessage) where T : class
    {
        if (instance == null)
        {
            throw new InvalidOperationException(exceptionMessage);
        }
    }

    private static string CreateNotFoundErrorMessage(string tableName, string code)
    {
        var errorMessage =  $"{tableName} does not contain required record with field Code={code}";
        return errorMessage;
    }

    private static bool IsValidVdiRunScopeCode(string vdiRunScopeCode)
    {
        return vdiRunScopeCode == VdiRunScopeCodeDataModel.Full || vdiRunScopeCode == VdiRunScopeCodeDataModel.Partial;
    }

    private static bool IsValidVdiRunTypeCode(string vdiRunTypeCode)
    {
        return vdiRunTypeCode == VdiRunTypeCodeDataModel.Products;
    }

    private static VdiRunHistoryInternalDataModel CreateVdiRunHistoryInternalModel(int operatorId, int vdiRunTypeId, int vdiRunScopeId)
    {
        return new VdiRunHistoryInternalDataModel
        {
            OperatorId = operatorId,
            VdiRunTypeId = vdiRunTypeId,
            VdiRunScopeId = vdiRunScopeId
        };
    }

    private VdiRunHistoryInternalDataModel FindVdiRunHistory(int operatorId, int vdiRunTypeId, int vdiRunScopeId)
    {
        var foundVdiRunHistory = _connection.SingleOrDefault<VdiRunHistoryInternalDataModel>(p =>
            p.OperatorId == operatorId &&
            p.VdiRunTypeId == vdiRunTypeId &&
            p.VdiRunScopeId == vdiRunScopeId);

        return foundVdiRunHistory;
    }
}

有一个IDbConnectionWrapper注入数据管理器:

public interface IDbConnectionWrapper
{
    void ExecuteSql(string sql);
    IReadOnlyCollection<T> Query<T>(string sql, object anonymousType);
    T SingleOrDefault<T>(Expression<Func<T, bool>> predicate);
    void Save<T>(T instance) where T : new();
}

我使用Moq库来编写测试。问题是模型(类)*InternalDataModels是非公开的“原始”模型,不应在被测程序集之外可见。正是在这些内部模型上SingleOrDefault<T> 调用方法和其他方法,这些是中间模型,然后用于获得最终结果。当试图锁定这些方法时,会出现一个逻辑错误,即模型不可用于被测组件。

问题:在这种情况下使用程序集的InternalVisibleTo属性好不好?还是有其他方法可以在不使用此属性的情况下编写测试?有谁知道如何重构此代码以使其可测试?

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-02-05 14:13:37 +0000 UTC

如何从 URL 中获取图像的原始方向?

  • 0

任务是根据其EXIF-data 正确显示图像(水平或垂直)。

现在服务器返回url格式的图像JPEG,但是当这个图像url用作src图像(标签img)时,网站上此类图像的方向将始终是水平的,即使照片是从手机垂直拍摄的。如果您转到图像的 url,那么在浏览器中它将以正确的方向显示。我怀疑标签img不知道如何识别图像的方向。有一个css-property image-orientation,但是只支持,还firefox需要支持chromeIE

我计划在服务器上下载一张图片并从那里获取元数据EXIF以确定方向。但这可能是服务器上的额外负载。谁遇到过这样的问题?问题是如何解决的?有哪些想法?

如果方向是在服务器端确定的,很高兴看到一个实现

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-11-30 01:17:15 +0000 UTC

C#。将两个集合合并为一个,排序,然后按条件拆分

  • 0

有两种类型(有条件):

public class ItemNumber
{
    public int Number { get; set; }
    public string Common { get;set; }
    public int Order { get; set; }
}


public class ItemString
{
    public string Common { get;set; }
    public int Order { get; set; }
}

有两个充满数据的集合:

// Они заполнены данными
var numbers = new List<ItemNumber>(); 
var letters = new List<ItemString>(); 

必要的(这里的步骤顺序可以是任意的):

  1. 将集合的元素插入numbers到集合中letters;
  2. letters按属性排序Order;
  3. 将集合拆分letters为子集合,其中拆分的边界将是(注意!numbers )我们从中插入并具有值Numbers = 4(例如)的那些元素,而这些元素本身Numbers = 4不应该包含在结果集合中。

以前,我不需要按条件拆分集合(参见第 3 项),只需要第 1项和第 2 项。我是这样使用 LINQ 做到的:

private static IReadOnlyCollection<ItemString> MergeCollections(IReadOnlyCollection<ItemNumber> numbers, IReadOnlyCollection<ItemString> letters)
{
    var result = new List<ItemString>(letters);

    result.AddRange(numbers.Select(p => new ItemString
    {
        Common = p.Common,
        Order = p.Order
    }));

    result = result.OrderBy(p => p.Order).ToList();
    return result;
}

我坐在这里折磨这个任务,如何最好地完成它。有一个想法是通过两个变量的循环来做到这一点,但到目前为止这个想法是模糊的。你能建议这个问题的最佳解决方案吗?可以用 LINQ 做到这一点吗?如果没有,我想看看算法的详细描述。

c#
  • 1 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-09-20 14:42:21 +0000 UTC

如何为 Windows 上的所有新 Angular 应用程序全局设置 node_modules 文件夹?

  • 1

我开始尝试Angular。使用命令创建新的 Angular 应用程序时ng new app-name,会创建一个新文件夹,其中包含另一个文件夹node_modules。命令本身ng new需要很长时间才能完成。我怀疑这与加载 node_modules 中的所有模块有关。

如何加载node_modules一次到某个文件夹(有条件地,D:\node_modules),并且在创建新项目时,Angular 会从该文件夹中拉出所有模块?然后每次创建应用程序时不断从 Internet 加载 200+ MB 就是这样的事情。我还想知道是否有一个命令可以让您更新这些模块。

还有一个普遍的问题:有必要这样做吗?

angular
  • 3 个回答
  • 10 Views
Martin Hope
Andrei Khotko
Asked: 2020-09-13 15:57:47 +0000 UTC

如何访问 .NET Framework 项目中的 ASP.NET Core 配置?

  • 0

有一个 ASP.NET Core 项目。它有一个web.config包含connectionString. 还有一个项目Data Layer(.NET Framework 类库)。在其中,我试图connectionString像这样进入类构造函数:

public DataManager()
{    
    ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Test"].ConnectionString.ToString();
}

事实是调试器甚至没有进入构造函数本身,在此之前它被抛出FileNotFoundException:

“无法加载文件或程序集‘System.Configuration.ConfigurationManager,Version=0.0.0.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51’。系统找不到指定的文件。”

有没有办法从项目中的连接字符串中获取项目中的.NET Framework class library连接web.config字符串ASP.NET Core?

.net
  • 1 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5