c# - 如何将带有 ref 参数的函数转换为异步函数?

标签 c# iis android-asynctask async-await

我有以下函数,我想将其转换为异步/非锁定函数。

这是当前形式的函数:

   private static void BlockForResponse(ref bool localFlag)
    {
        int count = 0;
        while (!localFlag)
        {
            Thread.Sleep(200);
            if (count++ > 50)   // 200 * 50 = 10 seconds
            {
                //timeout
                throw new TimeOutException();
            }
        }
    }

这是我的尝试:

  private static async Task BlockForResponse(ref bool localFlag)
    {
        int count = 0;
        while (!localFlag)
        {
            await Task.Delay(200);
            if (count++ > 50)   // 200 * 50 = 10 seconds
            {
                //timeout
                throw new TimeOutException();
            }
        }
    }

但是我收到一个编译错误,指出异步函数不能有 ref 或 out 参数。然而,这是该函数的核心功能。

是否可以将其转换为异步函数?

代码解释:

我必须承认这是一段奇怪的代码,让我试着解释一下它试图做什么:

所以我需要使用第 3 方 dll。它为我提供服务,遗憾的是我无法控制这个 dll。

它的工作方式, 我在 dll 中调用一个命令,为它提供一个回调函数,它在完成任务后调用该函数。

只有在收到该电话的结果后,我才能继续我想做的事情。因此需要此功能。

我调用 dll,为其提供回调函数:

    private bool _commandFlag = false;
    private bool _commandResponse;

    public async Task ExecuteCommand(string userId, string deviceId)
    {
        var link = await LinkProviderAsync.GetDeviceLinkAsync(deviceId, userId);
        try
        {               
            //execute command
            if (link.Command(Commands.ConnectToDevice, CallBackFunction))
            {
                BlockForResponse(ref _commandFlag);
                return;     //Received a response
            }
            else
            {   //Timeout Error                    
                throw new ConnectionErrorException();
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    private void CallBackFunction(bool result)
    {
        _commandResponse = result;
        _commandFlag = true;
    }

最佳答案

The way it works, I call a command in the dll providing it a callback function which it calls once it has finished the task.

那么你真正想要的是使用TaskCompletionSource<T>创建一个 TAP 方法,一些东西 similar to this .

public static Task<bool> CommandAsync(this Link link, Commands command)
{
  var tcs = new TaskCompletionSource<bool>();
  if (!link.Command(command, result => tcs.TrySetResult(result)))
      tcs.TrySetException(new ConnectionErrorException());
  return tcs.Task;
}

有了这个扩展方法,你的调用代码就干净多了:

public async Task ExecuteCommand(string userId, string deviceId)
{
  var link = await LinkProviderAsync.GetDeviceLinkAsync(deviceId, userId);
  var commandResponse = await link.CommandAsync(Commands.ConnectToDevice);
}

关于c# - 如何将带有 ref 参数的函数转换为异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26647111/

相关文章:

c# - 每台机器都使用相同的种子生成相同的随机数结果吗?

c# - 我应该使用 Html.CheckBox 还是 Html.CheckBoxFor?

Azure WebApp 删除错误请求的 'Server' header

java - 如何延迟页面或 sleep 线程直到下载过程或进度条完成

c# - 是否可以配置从 Nginx 到 kestrel aspnet core 的 kerberos 转发

c# - 当我在单独的线程上将随机数添加到列表框时,UI 卡住

.net - 时间作为决定性值(value)

asp.net - 如何允许匿名用户访问虚拟目录

java - Android 回调监听器 - 从 SDK 中的 pojo 发送值到应用程序的 Activity

java - 如何等待异步任务中另一个类的方法在android中完成