如何取消使用Continuewith的任务?

时间:2019-02-21 10:52:07

标签: c# timeout signalr task

我在函数内有一个Task,这是整个函数:

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);

1 个答案:

答案 0 :(得分:0)

要允许原始线程取消任务,您需要传递取消令牌,然后通过取消源标记取消。

public class Program
{
  public static void Main()
  { 
    CancellationTokenSource source = new CancellationTokenSource();
    CancellationToken token = source.Token;
    var task=AsyncMain(token);
    source.Cancel();
    try
    {
    Console.WriteLine("Main after started thread");
    task.Wait();
    Console.WriteLine("Main after task finished");
    }
    catch (AggregateException )
    {
    Console.WriteLine("Exceptions in Task");
    }
  }

  public static async Task AsyncMain(CancellationToken token)
  {
    Console.WriteLine("In Thread at Start");
    try
    {
      await Task.Delay(10).ContinueWith(
        async task =>
        {
          Console.WriteLine("Not Cancelled");
        }
        ,token);
    }
    catch(OperationCanceledException )
    {
      Console.WriteLine("Cancelled");
    }
    Console.WriteLine("In Thread after Task");
  }
}

但是,正如其他人指出的那样,ContinueWith正在混合paragims,在这种情况下不需要。例如,您可以这样做;

public static async Task AsyncMain(CancellationToken token)
{
    Console.WriteLine("In Thread at Start");
    await Task.Delay(10);
    if(!token.IsCancellationRequested)
    {
        //await Clients.Caller.SendAsync("NoUsersFound");
        Console.WriteLine("Not Cancelled");
    }
    else
    {
        Console.WriteLine("Cancelled");
    }
}

或者您可以只检查用户列表是否为空,而无需执行取消任务的操作。