【问题标题】:Task.Delay creating System.ObjectDisposedException: 'Cannot access a disposed object' with SignalR groupTask.Delay 创建 System.ObjectDisposedException:使用 SignalR 组“无法访问已处置的对象”
【发布时间】:2020-07-13 07:35:16
【问题描述】:

我正在用 asp.net core 和 Signalr 编写代码,其中有一个方法:

public async void newGameTimer(int tableID )
        {
            bool stop = true;
            int val = 0;
            while (stop)
            {
                await Task.Delay(1000);
                val++;
                if (val > 5)
                {
                    stop = false;
                    newGame(tableID);
                }
            }
        }

然后在newGame(tableID)方法中,如下:

public async void newGame(int tableID)
{
    await Clients.Group(group).SendAsync("updateTotalPot", 200);
}

我正在通过 signalR 组向玩家组发送异步响应。但它给出了错误

'System.ObjectDisposedException: '无法访问已处理的对象。 ObjectDisposed_ObjectName_Name'

我进行了搜索并得到了回答,例如“Task.Dealy()”可以创建 ObjectDisposed 错误。 现在不明白,怎么解决这个问题。

我只想等待一段时间,然后向玩家群发送响应.. 有人可以帮助我吗?

项目:在线实时扑克游戏 扑克在线游戏,一群朋友可以在其中创建一张桌子并一起玩扑克。 前端:反应 后端:asn.net core、Signalr、Redis

逻辑: 第一个玩家通过调用方法创建表:

public async Task LoginWindow(string name, string password, int newTable, int joinTable)
{ 
   //- this method saves many keys in Redis in-memory like this
    dbr.StringSet("table" + "ToBet", 0);

  //- at end send reply with following command
     await Clients.Caller.SendAsync("updateMessage",  "Welcome to table no " + tableID);

//- then this method check, if second player has called this method, then calls the timer to start game after 5 seconds

  newGameTimer(tableID);
 
}


nothing else...

【问题讨论】:

  • 在-ve 投票之前,请告诉我,为什么我应该投-ve 票,因为我试图解决问题好几个小时,但无法做到......
  • 您有异常的堆栈跟踪吗?下一个问题:为什么async void 不是async Task?如果这是设计使然,而不是一种不好的做法,那么异常处理在哪里?
  • 实际上,“异步任务”正在创建相同的错误,就像它自动“处置”对象一样。所以我设置了 void,它解决了这个问题,但现在 'Task.delay()' 给出了同样的错误..
  • 实际上,'await Task.delay()' 造成问题,因为如果我删除该行,那么它可以正常工作并正确发送响应..
  • 简而言之,问题出在所示代码之外。请显示您在哪里调用newGameTimer() 的方法,然后我将使用固定代码回答问题。您可以编辑问题。

标签: c# asp.net signalr


【解决方案1】:

这里不需要async void。解决方案可能如下所示。

public async Task NewGameWithDelay(int tableID)
{
    for (int i = 0; i < 5; i++)
    {
        if (await CheckForSecondPlayer())
        {
            // found
            await Clients.Group(group).SendAsync("updateTotalPot", 200);
            return;
        }
        await Task.Delay(1000);
    }
    // not found
}

private async Task<bool> CheckForSecondPlayer()
{
    // if found return true, else
    return false;
}
public async Task LoginWindow(string name, string password, int newTable, int joinTable)
{ 
    dbr.StringSet("table" + "ToBet", 0);
    await Clients.Caller.SendAsync("updateMessage",  "Welcome to table no " + tableID);
    await NewGameWithDelay(tableID);
}

【讨论】:

  • 我已经尝试过这个解决方案,但它对我没有帮助,并且给了我同样的错误“ObjectDisposed”,实际上我不能直接延迟 5 秒,因为我必须检查每一秒,如果有任何新玩家..请告诉我,有没有其他方法可以让异步等待,这样我就可以避免 Task.delay()。
  • 明天我会重新开始新的尝试,因为现在是凌晨 2 点。亲爱的,我会更新你的。顺便说一句,感谢您的宝贵时间。
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多