简体   繁体   English

如何在 C# 中更好地将 continueWith 替换为 async/await

[英]how to do it better replace continueWith to async/await in C#

I have C# code:我有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;
    }
}       

I need replace continueWith to await .我需要替换continueWithawait And I try in this example:我在这个例子中尝试:

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

But taskDisposeTokenUnreg has no field Result and and you can't write like that await taskCompletionSource.Task.Result .但是taskDisposeTokenUnreg没有字段Result并且你不能这样写await taskCompletionSource.Task.Result How best to replace this code?如何最好地替换此代码?

When you use the await operator on a Task , the value you get is the result of the Task .当您在Task上使用await运算符时,您获得的值是Task的结果。

So in your case, taskDisposeTokenUnreg will already be the UserActionResult value you are looking for.因此,在您的情况下, taskDisposeTokenUnreg将已经是您正在寻找的UserActionResult值。 You can just return taskDisposeTokenUnreg .您可以只return taskDisposeTokenUnreg

Your original method has a synchronous signature;您的原始方法具有同步签名; all the code in that method (except the delegates) is executed immediately.该方法中的所有代码(委托除外)都会立即执行。 The ContinueWith delegate is the only code that executes later , after the taskCompletionSource.Task completes.taskCompletionSource.Task完成之后ContinueWith委托是稍后执行的唯一代码。 So, to duplicate this behavior, you need to move the ContinueWith delegate to the end of the method, so all the synchronous code executes first just like it did before:因此,要复制此行为,您需要将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;
}

Once you're using async / await , then you can simplify further by using a using declaration:使用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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM