2017-07-05 10 views
0

非同期メソッドからクラスを返すことはできますか? 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

どのような言語ですか。 – deceze

+2

[ReadAsync'](https://msdn.microsoft.com/en-us/library/hh137813(v = vs.110))からの戻り値をチェックしていないと、間違いがあります。 aspx)。それは1バイトだけ戻ってくるかもしれません。 –

答えて

-1
StatusButton.Click += async (sender, e) => 
{ 
    ... 
    byte[] TheResponse = new byte[1024]; 
    TheResponse = await client.Read();   // <---- place await in the correct place 
}; 
2

それは非同期メソッドからクラスを返すことは可能ですか?

はい。

GetAwaiterが見つからないというエラーメッセージが表示されるのはどういう意味ですか?

それは変数、すなわちTheResponseしかし、あなたがTask<byte[]>としてそれを割り当てるしようとしている、byte[]として宣言したことを意味します。しかし、IDEにはasyncキーワードの使用に関する先験的なチェックがあり、あなたが試行しようとしているタイプについてGetAwaiterメソッドがないという文句を言う。これはbyte[]であるためです。この問題を示す.NET fiddleの例を示します。

私はここに注意を喚起したいことはほとんどありません。まず、戻り値の型がTaskTask<T>またはその他の非同期戻り値の型である場合、メソッドに「Async」という接尾辞、つまり、名前を付けることをお勧めします。 ReadAsync。さらに、それより明白であることを傷つけることはありません。あなたはこの方法からTask<byte[]>を返すことしかできないので、それをReadBytesAsyncと呼んでいますか?

ここで、明確に定義されたクライアントと対応するAPIがあるので、その使用方法を見てみましょう。対応するawaitキーワードの使用を可能にするasyncキーワードを使用する場合。これらの2つのキーワードは一緒に機能し、決して単独で使用することはできません。

Task<byte[]>のことを約束しておいてください。しばらくしてからbyte[]をお渡ししますが、これを "待つ"必要があります。あなたのコードでは、awaitを間違った場所に置いています。代わりに、次のことを持っている必要があります。

StatusButton.Click += async (sender, e) => 
    { 
     ... 

     byte[] bytes = await client.ReadBytesAsync(); 
    }; 

だけあなたが行っていたとして、それを再割り当てしようとする変数を宣言して初期化する理由はありません。その代わりに、呼び出された呼び出しの応答から.ReadBytesAsync呼び出しまでの値を単純に宣言して初期化します。 awaitキーワードがないと、非同期操作を表すTask<byte[]>があることに注意してください。

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; 
     } 
    } 
関連する問題