12

私のOperationContract

public List<MessageDTO> GetMessages()
        {
            List<MessageDTO> messages = new List<MessageDTO>();
            foreach (Message m in _context.Messages.ToList())
            {
                messages.Add(new MessageDTO()
                {
                    MessageID = m.MessageID,
                    Content = m.Content,
                    Date = m.Date,
                    HasAttachments = m.HasAttachments,
                    MailingListID = (int)m.MailingListID,
                    SenderID = (int)m.SenderID,
                    Subject = m.Subject
                });
            }
            return messages;
        }

サービス参照構成で、「非同期操作を生成する」オプションをチェックしました。生成された をどのように使用しますGetMessagesAsync()か? ネットで を使用する例を見つけましたがAsyncCallback、私はそれに慣れていません。.NET 4.5のキーワードasyncやキーワードのように使いやすい方法で使用する方法はありますか? awaitそうでない場合、メソッドを非同期で呼び出すにはどうすればよいですか?

4

4 に答える 4

8

「非同期操作を生成する」を選択すると、コールバックを使用する必要がある「古い」動作が得られます。

新しい async/await 構文を使用する場合は、[タスクベースの操作を生成する] を選択する必要があります (既定で選択されています)。

デフォルトの Wcf テンプレートを使用すると、次のプロキシ コードが生成されます。

  public System.Threading.Tasks.Task<string> GetDataAsync(int value) {
      return base.Channel.GetDataAsync(value);
  }

ご覧のとおり、コールバックはもうありません。代わりに aTask<T>が返されます。

このプロキシは、次の方法で使用できます。

public static async Task Foo()
{
    using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
    {
        Task<string> t = client.GetDataAsync(1);
        string result = await t;
    }
}

呼び出し元のメソッドを でマークしてから、サービス メソッドを呼び出すときasyncに使用する必要があります。await

于 2012-12-08T14:14:34.137 に答える
3

サービス参照は、(.Net 4.5 を使用している場合) タスクベースの非同期呼び出しを生成するように設定できます。(サービス参照を構成する > 非同期操作の生成を許可するをチェックする > タスクベースの操作を生成するを選択する) これらは、任意のasyncメソッドと同様に使用できます。使用方法の例を次に示します。

using (var proxy = new YourServiceClient())
{
    var t1 = proxy.GetMessagesAsync();
    var t2 = proxy.GetMessagesAsync();
    //they're runnning asynchronously now!

    //let's wait for the results:
    Task.WaitAll(t1, t2);
    var result1 = t1.Result;
    var result2 = t2.Result;
    Console.WriteLine(result1);
    Console.WriteLine(result2);
}

クライアントが .Net 4.5 を使用していない場合、.NET を使用するサービス参照を生成できませんasync。コールバックを使用して、昔ながらの方法で行う必要があります。次に例を示します。

static void m()
{
    var proxy = new YourServiceClient();
    proxy.GetMessagesCompleted += proxy_GetMessagesCompleted;
    proxy.GetMessagesAsync();
}

static void proxy_GetMessagesCompleted(object sender, GetMessagesCompletedEventArgs e)
{
    var proxy = (IDisposable)sender;
    proxy.Dispose(); //actual code to close properly is more complex

    if (e.Error != null)
    {
        // do something about this
    }

    var result = e.Result;
    Console.WriteLine(result);
}

これらのシナリオのいずれかの実際のコードでは、クライアントを使用しusingたりIDisposable.Dispose()、クライアントをクリーンアップしたりしないでください。 Using ステートメントとこのコードに関する問題の回避を参照して、これらのものを閉じるという紛らわしい世界に取り掛かりましょう。

于 2012-12-08T13:55:39.917 に答える
1

VS2012 を使用している場合は、次の*Asyncような呼び出しを使用できます。

var proxy = new MyClient();
var result = await proxy.GetMessagesAsync();
于 2012-12-08T14:07:21.607 に答える
0

このようなものはどうですか...

public async Task<string> DoSomething()
{
var someProxy = new ServiceClient();

var t = someProxy.SomeMethodAsync();
await Task.WhenAny(t);

return t.Result;

}

于 2012-12-08T13:45:13.083 に答える