-1

我有C#代码:

public class SimpleClass{

    public Task<TestClass> WaitForUserInput(IResource resource, CancellationToken token)
    {
        var button = resource.GetResource();

        var taskCompletionSource = new TaskCompletionSource<UserActionResult>();
        IDisposable cancellationTokenReg = token.Register(
                                      () => taskCompletionSource.SetResult(new TestClass()));

        var taskDisposeTokenUnreg = taskCompletionSource.Task.ContinueWith(
            task =>
                {
                    cancellationTokenReg.Dispose();
                     return task.Result;
                 });

        button.TouchEvent += Subscribe;
        button.Disabled = true;

        return taskDisposeTokenUnreg;
    }
}       

我需要更换continueWithawait. 我在这个例子中尝试:

public class SimpleClass{

    public async Task<TestClass> WaitForUserInput(IResource resource, CancellationToken token)
    {
        var button = resource.GetResource();

        var taskCompletionSource = new TaskCompletionSource<UserActionResult>();
        IDisposable cancellationTokenReg = token.Register(
                                      () => taskCompletionSource.SetResult(new TestClass()));

        var taskDisposeTokenUnreg = await taskCompletionSource.Task
        cancellationTokenReg.Dispose();
        return taskDisposeTokenUnreg.Result;

        button.TouchEvent += Subscribe;
        button.Disabled = true;

        return taskDisposeTokenUnreg;
    }
}     

但是taskDisposeTokenUnreg没有领域Result,你不能那样写await taskCompletionSource.Task.Result。如何最好地替换此代码?

4

2 回答 2

1

当您在 a 上使用await运算符Task时,您获得的值是Task.

因此,就您而言,taskDisposeTokenUnreg这已经是UserActionResult您正在寻找的价值。你可以return taskDisposeTokenUnreg

于 2019-12-25T18:44:28.813 回答
0

您的原始方法具有同步签名;该方法中的所有代码(委托除外)都会立即执行。委托是完成后ContinueWith唯一稍后执行的代码taskCompletionSource.Task。因此,要复制此行为,您需要将ContinueWith委托移动到方法的末尾,以便所有同步代码首先执行,就像以前一样:

public async Task<TestClass> WaitForUserInput(IResource resource, CancellationToken token)
{
  var button = resource.GetResource();

  var taskCompletionSource = new TaskCompletionSource<UserActionResult>();
  IDisposable cancellationTokenReg = token.Register(
                                      () => taskCompletionSource.SetResult(new TestClass()));

  button.TouchEvent += Subscribe;
  button.Disabled = true;

  var result = await taskCompletionSource.Task;
  cancellationTokenReg.Dispose();
  return result;
}

使用async/await后,您可以使用using声明进一步简化:

public async Task<TestClass> WaitForUserInput(IResource resource, CancellationToken token)
{
  var button = resource.GetResource();

  var taskCompletionSource = new TaskCompletionSource<UserActionResult>();
  using var cancellationTokenReg = token.Register(
                                      () => taskCompletionSource.SetResult(new TestClass()));

  button.TouchEvent += Subscribe;
  button.Disabled = true;

  return await taskCompletionSource.Task;
}
于 2019-12-27T17:03:32.837 回答