【问题标题】:Call asynchronous method on a WCF service with Single InstanceContextMode使用 Single InstanceContextMode 在 WCF 服务上调用异步方法
【发布时间】:2018-12-21 08:23:28
【问题描述】:

我正在尝试异步调用具有单个 instanceContextMode 的 WCF 上的方法。

有没有办法在等待异步方法时重用服务实例?我使用 Task 方式在我的 WCF 服务引用上生成异步操作。

我做了一个测试项目,因为我的应用程序出现了一些问题。 我的 TestService 公开了 2 个方法:

    - 一个应该同步调用的快速方法
    - 一个应该被异步调用的长方法

由于某些其他原因,我的服务应该是 Single instanceContextMode:

[ServiceContract]
public interface ITestService
{
    [OperationContract]
    string FastMethod(string name);

    [OperationContract]
    Task<string> LongMethodAsync(string name);
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class TestService : ITestService
{
    public TestService() { }

    public string FastMethod(string name)
    {
        Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - FastMethod call - {name}");
        return $"FastMethod - {name}";
    }

    public async Task<string> LongMethodAsync(string name)
    {
        for (int i = 5; i > 0; i--)
        {
            await Task.Delay(1000);
            Console.WriteLine($"LongMethod pending {i}");
        }

        Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - LongMethod call - {name}");
        return $"LongMethod - {name}";
    }
}

我的主机是一个简单的控制台应用程序,它允许我通过 Console.WriteLine() 方法查看 WS 调用:

class Program
{
    static void Main(string[] args)
    {
        using (ServiceHost hostTest = new ServiceHost(typeof(TestService)))
        {
            Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Service starting...");
            hostTest.Open();
            Console.WriteLine($"{DateTime.Now.ToLongTimeString()} - Service started");
            Console.ReadKey();
            hostTest.Close();
        }
    }
}

在我的客户端,我只有一个显示结果调用的简单表单:

private async void button1_Click(object sender, EventArgs e)
{
    string result;
    result = srvClient.FastMethod("test1");
    resultTextBox.Text = $"{DateTime.Now.ToLongTimeString()} - {result}";

    Task<string> t1 = srvClient.LongMethodAsync("test2");

    result = srvClient.FastMethod("test3");
    resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";

    System.Threading.Thread.Sleep(1000);
    result = srvClient.FastMethod("test4");
    resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";

    result = await t1;
    resultTextBox.Text += $"\r\n{DateTime.Now.ToLongTimeString()} - {result}";
}

当我这样做时,我可以在我的 resultTestBox 和主机控制台中看到“test3”和“test4”仅在“test2”结束后被调用。

如果我在本地(不是通过 WCF 服务)进行相同的测试,行为就像预期的那样,在“test2”等待时调用“test3”和“test4”。

【问题讨论】:

    标签: c# wcf async-await


    【解决方案1】:

    According to MSDN:

    如果 InstanceContextMode 值设置为 Single,则结果是您的服务一次只能处理一条消息,除非您还将 ConcurrencyMode 值设置为 ConcurrencyMode。

    (好像他们忘了说什么并发模式)

    所以只需在您的服务上设置正确的ConcurrencyMode

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    

    请确保您的代码是无状态且线程安全的。这种组合很容易出错。

    【讨论】:

    • 谢谢,我刚刚测试过,它似乎有效。
    猜你喜欢
    • 2014-04-30
    • 2011-10-30
    • 2012-12-30
    • 1970-01-01
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多