是否可以从异步方法返回一个类?我收到一条错误消息,指出GetAwaiter
丢失了?不知道这意味着什么。
StatusButton.Click += async (sender, e) =>
{
...
byte[] TheResponse = new byte[1024];
await TheResponse = client.Read(); // <---- GetAwaiter ?
};
public class Client
{
...
public async Task<byte[]> Read()
{
var ns = tcpClient.GetStream();
byte[] Result = new byte[1024];
await ns.ReadAsync(Result, 0, Result.Length);
return Result;
}
}
答案 0 :(得分:2)
是否可以从异步方法返回一个类?
是
我收到一条错误消息,指出GetAwaiter丢失了,这是什么意思?
这意味着变量TheResponse
被声明为byte[]
,但您尝试将其指定为Task<byte[]>
。但是,IDE会对async
关键字的使用进行抢先检查,并向您抱怨您尝试等待的类型没有GetAwaiter
方法。这是因为它是byte[]
。以下是展示此问题的示例.NET fiddle
。
我想在这里引起很多关注。首先,当您的返回类型为Task
,Task<T>
或任何其他异步返回类型时 - 最佳做法是使用“Async”后缀命名该方法,即; ReadAsync
。此外,明确比这更明显。由于您只能从此方法返回Task<byte[]>
,我们称之为ReadBytesAsync
,是吗?
好的,现在我们有一个明确定义的客户端和相应的API让我们看一下它的用法。当您使用允许使用相应async
关键字的await
关键字时。这两个关键字协同工作,永远不能单独使用。
将Task<byte[]>
视为一种承诺,在某个时候我会给你一个byte[]
,但你必须“等待”这个。在您的代码中,您将await
置于错误的位置。相反,你应该有以下内容:
StatusButton.Click += async (sender, e) =>
{
...
byte[] bytes = await client.ReadBytesAsync();
};
没有理由声明和初始化变量只是为了尝试重新分配它,就像你所做的那样。相反,简单地声明并将等待的调用响应中的值初始化为.ReadBytesAsync
调用。请注意,如果没有await
关键字,您将拥有代表异步操作的Task<byte[]>
。
答案 1 :(得分:0)
非常感谢,现在它运行了。不得不做出一些改变。他们在这里:也许有人可以使用它。
protected override void OnCreate(Bundle bundle)
{
...
OpenButton.Click += delegate
{
SendCommand('O');
ThreadPool.QueueUserWorkItem(o => ShutDown());
};
...
}
async void SendCommand(Char Command)
{
... //Command not used in this part of code
const string sn = "SEND_NONCE";
byte[] data = System.Text.Encoding.ASCII.GetBytes(sn);
Client client = new Client();
TcpClientPacket TheData = new TcpClientPacket(sn.Length);
TheData.Buffer = data;
TheData.Length = sn.Length;
bool IsConnected = await client.InitializeAsync(HostUrl, Port);
...
await client.WriteAsync(TheData);
TcpClientPacket TheResponse = await client.ReadAsync(16);
...
}
public class Client
{
private TcpClient tcpClient;
public async Task <bool> InitializeAsync(string ip, int port)
{
tcpClient = new TcpClient();
try
{
await tcpClient.ConnectAsync(ip, port);
}
catch
{
return false;
}
return tcpClient.Connected;
}
public void Deactivate()
{
tcpClient.Close();
}
public async Task WriteAsync(TcpClientPacket Data)
{
var ns = tcpClient.GetStream();
await ns.WriteAsync(Data.Buffer, 0, Data.Length);
}
public async Task<TcpClientPacket> ReadAsync(int ExpectedLength)
{
var ns = tcpClient.GetStream();
TcpClientPacket Result = new TcpClientPacket(ExpectedLength);
Result.Length = await ns.ReadAsync(Result.Buffer, 0, ExpectedLength);
return Result;
}
}
public class TcpClientPacket
{
public byte[] Buffer;
public int Length;
public TcpClientPacket(int Size)
{
Buffer = new byte[Size];
Length = 0;
}
}
答案 2 :(得分:-1)
StatusButton.Click += async (sender, e) =>
{
...
byte[] TheResponse = new byte[1024];
TheResponse = await client.Read(); // <---- place await in the correct place
};