【发布时间】:2019-07-15 06:19:56
【问题描述】:
我在一个函数中有一个任务,这是整个函数:
public async Task CreateRoom(GameTypes game)
{
// Get the user that called this function
User CurrentUser = ConnectedUsers.Single(r => r.Id == Context.ConnectionId);
// Set the user name to Player 1
CurrentUser.Name = "Player 1";
// Add the user to a new list of Users and add that list to the Room
UsersInRoom = new List<User>();
UsersInRoom.Add(CurrentUser);
Room room = new Room() { RoomName = CurrentUser.Name, Game = game, UsersInRoom = UsersInRoom };
AllRooms.Add(room);
// Subscribe the user to the lobby
await Groups.AddToGroupAsync(CurrentUser.Id, CurrentUser.Name);
CurrentUser.Room = CurrentUser.Name;
// Send to the user that the wait screen needs to be opened
await Clients.Caller.SendAsync("OpenWaitScreen");
// Send to all other users to update the lobby list.
await Clients.Others.SendAsync("ForceRoomRequest", game);
// If in 5 minutes no user joins the lobby than send to the caller NoUsersFound
await Task.Delay(300000).ContinueWith(async task =>
{
await Clients.Caller.SendAsync("NoUsersFound");
AllRooms.Remove(room);
});
}
我在 Stackoverflow 上找到了一些东西,但我不知道如何实现它们。
但我希望能够在其他功能中取消此任务。
我该怎么做?
编辑:这是我想重写为 C# 的一段 javascript 代码:
setTimeout(function (){
socket.emit('NoUsersFound');
delete AllRooms[data.room];
}, 300000);
【问题讨论】:
-
如果你使用 async/await,不要使用
.ContinueWith -
@Liam 这意味着您的读者现在需要彻底理解两个独立的异步模型,其中一个在许多情况下根本不直观。几乎所有 ContinueWith 能做的事情,async/await 都能以更易读的方式完成。
-
@Liam 例如,在这种情况下,您是否会猜到
ContinueWith没有重载,该任务是Func<Task, Task>,因此返回Task<Task>。因此,父任务不会等到其子任务完成,而是等到调用了SendAsync方法。你真正需要做的是await await Task.Delay(...)...,或者使用.Unwrap()。不,大多数人会在这中间迷路。如果您只想使用同步代码进行 fork/join,请使用 ContinueWith,如果您想要异步,请使用 async/await。不要混合它们。 -
@BlueDragon709 使用 CancellationTokenSource 并在任何接受它的异步操作中传递 CancellationToken,包括
Task.Delay和ContinueWith。Task.Delay(300000).ContinueWith很奇怪,为什么不分别调用和等待每个操作呢?