【问题标题】:Something like Session for a Console Application类似于控制台应用程序的会话
【发布时间】:2018-01-30 21:32:44
【问题描述】:

我正在为电报机器人开发一个控制台应用程序。

我有一个NextFiledStrig,它告诉应用程序应该向用户询问哪个字段。当多个用户与机器人或应用程序通信时,NextFiledStrig 会发生变化。

是否有类似会话的东西,所以我可以为每个用户在其中存储NextFiledStrig?还是我必须一遍又一遍地从数据库中获取它的价值?

我工作过 ASP.net C#,我是控制台应用程序的新手。

我搜索了很多,但找不到任何解决我问题的方法。很多人的回答是:它是一个控制台应用程序,只有一个用户,你不需要会话。

【问题讨论】:

  • 我猜通常 BOT 框架会有会话管理功能。您应该考虑在主机应用程序中进行会话管理。

标签: c# console-application telegram-bot


【解决方案1】:

控制台应用程序中没有会话。但是你可以使用一个简单的字典来存储你的数据:

private static Dictionary<User, NextFiledStrig> s_nextFiledByUser = new Dictionary<User, NextFiledStrig>();

private static GetNextFiledForUser(User user) {
    NextFiledStrig value;
    bool isCached = s_nextFiledByUser.TryGetValue(user, out value);
    if (!isCached) {
        value = new NextFiledStrig(); //Replace this with the code that will get the value
        nextFiledByUser.Add(user, value);
    }
    return value;
}

【讨论】:

  • 我认为数据库是最好的解决方案。因为应用程序可能会崩溃或关闭。
  • @MahdiHesari,您可以将这些值存储到 AppData 文件夹中的文件中,与使用 DB 相比,它应该具有更好的性能。
  • @KimHoang,当你必须处理多线程时,使用数据库会让你的生活变得更轻松(我假设 Telegram 机器人必须处理来自不同线程的命令)
  • @KimHoang:控制台应用程序中没有 AppData 文件夹。
【解决方案2】:

如果您只能使用控制台应用程序,请不要想。没有这样的。您只能使用数据库来存储键的值。但是请告诉我用户如何调用这个机器人?

【讨论】:

  • 可能来自网络应用?
  • 您可以将参数与请求一起使用。
  • 你能解释更多吗?
  • 在机器人访问命令行参数中放置一个字段,例如 NextFiledSrig,当此请求到达您的机器人时,您的机器人会根据需要解析您的字段。
  • 我决定使用数据库。谢谢你
【解决方案3】:

我使用 AsyncLocal 为我的客户端-服务器应用程序实现了一个会话系统,我将尝试解释它:

如果您异步运行每个客户端连接处理程序:

  • 使用 AsyncLocal 创建一个类来保存会话数据
public class Session
{
    private static AsyncLocal<IDictionary<string,object>> _Data = new AsyncLocal<Dictionary<string,object>>();

    public static IDictionary Data
    {
        set
        {
            _Data.Value = value;
        }
        get
        {
            return _Data.Value;
        }
    }
}
  • 异步管理每个客户端连接:
// fire the client manager and go to keep listening for client connections.
Task manager = Task.Run(async () => await Client.Start())
  • 将 Session 数据分配给新字典:
public async Task Start()
{
    Session.Data = new Dictionary<string,object>();

    // Do your receive, manage the bytes, etc.
}

这样,即使是静态属性,Session.Data 在该异步任务和子任务上也是唯一的。

举个例子:

Session.Data = new Dictionary<string,object>() {{"value", 1}}

Console.WriteLine(Session.Data["value"].toString()); // will be 1

Task manager1 = Task.Run(async () => 
{
    Console.WriteLine(Session.Data["value"].toString()); // will be 1
    Session.Data = new Dictionary<string,object>() {{"value", 2}}
    Console.WriteLine(Session.Data["value"].toString()); // will be 2

    Task manager2 = Task.Run(async () => 
    {
        Console.WriteLine(Session.Data["value"].toString()); // will be 2
        Session.Data = new Dictionary<string,object>() {{"value", 3}}
        Console.WriteLine(Session.Data["value"].toString()); // will be 3
    }

    Task manager3 = Task.Run(async () => 
    {
        Console.WriteLine(Session.Data["value"].toString()); // will be 2
        Session.Data = new Dictionary<string,object>() {{"value", 4}}
        Console.WriteLine(Session.Data["value"].toString()); // will be 4
    }

    Console.WriteLine(Session.Data["value"].toString()); // will be 2
}

Console.WriteLine(Session.Data["value"].toString()); // will be 1

希望这对您有所帮助,或者至少指出一个好的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多