Удаление контекста SignalR и базы данных - PullRequest
1 голос
/ 19 апреля 2019

Я пытался заставить SignalR запустить запрос к базе данных, а затем в зависимости от результата этого запроса ответить клиенту, который его инициировал.

Но я столкнулся с Невозможно получить доступ к удаленному объекту. из DatabaseContext и HubContext .Я испробовал несколько различных методов создания одного контроллера базы данных среди других, но ни один из них не сработал.

Мне наконец удалось создать решение, но теперь мне интересно, создаю ли я слишком много экземпляров / контекстов базы данныхконтекст.

Вот метод, который я придумал.(Упрощенно)

[Authorize(JwtBearerDefaults.AuthenticationScheme)]
public class Game : Hub
{
    private GameContext _dbContext;
    private IHubContext<Game> _hubContext;

    public Game(IHubContext<Game> hubContext)
    {
        _hubContext = hubContext;
    }

    public override async Task OnConnectedAsync()
    {
        await Clients.Client(Context.ConnectionId).SendAsync("DebugMessage", "Connected to Hub");
        await base.OnConnectedAsync();
    }

    public async void NewUser(string username, string userIdentifier)
    {
        _dbContext = new GameContext { };
        string connectionID = Context.ConnectionId;

        bool error = false;
        bool usernameExists = false;
        bool createdUser = false;

        try
        {
            var rows = await _dbContext.Users.Where(x => x.Username == username).ToListAsync();
            if (rows.Count > 0)
            {
                usernameExists = true;
                goto SendResponse;
            }
        }
        catch (Exception e)
        {
            error = true;
            goto SendResponse;
        }

        Users user = new Users { Username = username, UserIdentifier = userIdentifier, Joined = DateTime.UtcNow };
        try
        {
            _dbContext.Add(user);
            await _dbContext.SaveChangesAsync();
            createdUser = true;
            goto SendResponse;
        }
        catch (Exception e)
        {
            error = true;
            goto SendResponse;
        }

        SendResponse:
            await _hubContext.Clients.Client(connectionID).SendAsync("CreatedUser", username, usernameExists, createdUser, error);
    }

}

Как вы можете видеть в функции NewUser , я создаю новый экземпляр / контекст, чтобы он тоже работал.

Такое ощущение, что эторасточительно, поэтому сделайте шаблон Singleton для него в Game Hub, чтобы проверить, является ли он нулевым, и создайте новый, если необходимо, следующим образом.

private Object padlock = new Object { };
private GameContext _dbContextInstance;
private GameContext _dbContext
{
    get
    {
        if (_dbContextInstance == null)
        {
            lock (padlock)
            {
                if (_dbContextInstance == null)
                {
                    _dbContextInstance = new GameContext { };
                }
            }
        }
        return _dbContextInstance;
    }
}

Но он все еще кажется расточительным, так как я постоянно делаю одно и то жеСнова и снова, когда пользователь делает много звонков, он складывается, поэтому, прежде чем я продолжу, я хотел бы знать, иду ли я по неверному маршруту с этим и если да, то по какому маршруту я должен идти.

Спасибо

1 Ответ

1 голос
/ 19 апреля 2019

Ваш код должен выглядеть следующим образом

// this has to be a task, otherwise the framework
// cannot know when it has finished 
public async Task NewUser(string username, string userIdentifier)
{
    using (var dbContext = new GameContext())
    {
        string connectionID = Context.ConnectionId;

        bool error = false;
        bool usernameExists = false;
        bool createdUser = false;

        try
        {
            usernameExists  = await dbContext.Users.AnyAsync(x=> x.Username == username);
        }
        catch (Exception e)
        {
            error = true;
        }

        if (!usernameExists && !error)
        {
            Users user = new Users { Username = username, UserIdentifier = userIdentifier, Joined = DateTime.UtcNow };
            try
            {
                dbContext.Add(user);
                await dbContext.SaveChangesAsync();
                createdUser = true;
            }
            catch (Exception e)
            {
                error = true;
            }
        }

        await _hubContext.Clients.Client(connectionID).SendAsync("CreatedUser", username, usernameExists, createdUser, error);
    }
}

Использование меток в C # не распространено.Вы должны позволить инфраструктуре позаботиться о том, как управляются соединения (единственная важная вещь), и это делается с помощью правильного выражения using.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...