当客户端处理或超出范围时,异步WCF调用会发生什么?

Sim*_*one 5 .net c# wcf asynchronous async-await

我正在维护一些代码,其中包含一个类,该类包含使用Task模式异步调用WCF方法的方法.

代码实际上看起来像这样:

public class Manager : IDisposable
{
    public void DoSomething()
    {
        Task<bool> task;

        using (var client = new WcfClient())
        {
            task = client.ReallyDoSomethingAsync(123);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

管理器本身在另一段代码中的其他地方使用,该代码包含对使用(Manager)块内的DoSomething的调用.

所以我的问题是,WCF调用会发生什么.会发生吗?它放弃了吗?

更一般地说,这适用于使用Task<T>模式的异步调用吗?如果拥有类在异步调用完成之前超出范围会发生什么?

Sim*_*one 5

敲下一个简短的测试应用程序后,似乎在处理WCF客户端时,它会等待所有异步任务在实际处理之前完成.

示例WCF服务:

 public class Service1 : IService1
 {
    public string GetData(int value)
    {
        Thread.Sleep(5000);

        return "GOT HERE " + value;
    }
 }
Run Code Online (Sandbox Code Playgroud)

示例客户端:

class Program
{
    static void Main(string[] args)
    {
        using (var wrapper = new Wrapper())
        {
            wrapper.DoSomething();
        }

        Console.WriteLine("Finished.");
        Console.ReadLine();
    }
}

class Wrapper : IDisposable
{
    public void DoSomething()
    {
        Task<string> task1;

        using (var client = new ServiceReference1.Service1Client())
        {
            task1 = client.GetDataAsync(1);
            var task2 = client.GetDataAsync(2);

            Thread.Sleep(1000);

            var task3 = client.GetDataAsync(3);

            Console.WriteLine("Calls started");
        }

        Console.WriteLine("Result of task 1:" + task1.Result);
    }

    public void Dispose()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,1秒延迟后出现"呼叫已启动"行."完成了".在所有三个任务都成功完成之前,不会写入行.

事实上,它实际上似乎WCF服务客户端包装器管理其任务并在处置之前等待完成(或可能是超时).

...让我想到的是:如果你想以"一次又一次"的异步方式调用一个长时间运行的WCF方法,你要么必须在没有using块的情况下执行它,要么将整个事情包装在自己的任务中.这就是很多包装!

  • 重要的是,“状态”显示任务不会被取消。所以现在我们知道:显然,WCF 服务的客户端代理在被处理时不会取消其挂起的任务。有趣的。这与我期望它的工作方式相反。一个好问题,+1。 (2认同)