我有以下函数,我想将其转换为异步/非锁定函数。
这是当前形式的函数:
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/