WCF服务调用产生多个线程

时间:2015-04-24 15:15:14

标签: c# multithreading wcf iis

我们正面临着WCF服务中断的问题(间歇性(在6个月内也是如此),我们无法在任何环境中复制该方案。)并停止提供进一步的请求,从而创建死锁方案。

我们通过使用async await来调用对数据库,其他WCF服务的多个调用。

我们怀疑服务超过了允许的最大线程数。

以下是我创建的示例,这有点像创建相同的行为

服务代码

public class Service1 : IService1
{
    public int GetDataUsingDataContract()
    {
        try
        {
            var result = this.GetNumberAsyc().Result;
            return result;
        }
        catch (Exception ex)
        {
            return 0;
        }
    }

    private async Task<int> GetNumberAsyc()
    {
        return await this.GetNumber();
    }

    public Task<int> GetNumber()
    {
        Task[] tArr = new Task[1000];

        for (int i = 0; i < 1000; i++)
        {
            tArr[i] = Task.Factory.StartNew(
                () =>
                {
                    Task delayTask = Task.Delay(1);
                    delayTask.Wait();
                }
                );
        }

        Task.WaitAll(tArr);

        return Task.Factory.StartNew<int>(
            () =>
            {

                Task delayTask = Task.Delay(200);
                delayTask.Wait();
                Random r = new Random();
                return r.Next();
            });
    }
}

我们还怀疑这可能是因为SynchronizationContext。

服务托管在IIS上。

有什么想法吗?

由于

更新

以下是IIS中托管的示例ASP.NET网页

 protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = (Test().ToString());
    }

    private int Test()
    {
        //var task = AsyncAwait_GetSomeDataAsync();
        //var data = task.GetAwaiter().GetResult();
        //var data = task.Result;

        var task1 = AsyncAwait_GetSomeDataAsync();
        //var data1 = task1.GetAwaiter().GetResult();
        var data1 = task1.Result;

        return data1;
    }

    protected async Task<int> AsyncAwait_GetSomeDataAsync()
    {
        var httpClient = new HttpClient();

        var result = await httpClient.GetAsync("http://www.google.com", HttpCompletionOption.ResponseHeadersRead); //.ConfigureAwait(false);

        return result.Content.Headers.ToString().Length;
    }

此代码不起作用,如果我们在WCF服务中编写相同的代码并在IIS中托管服务,则相同的代码运行良好。

在两者都托管在IIS中时,WCF和ASP.NET如何管理上下文是否有区别。

由于

1 个答案:

答案 0 :(得分:0)

如果没有线程完成其工作并且在ThreadPool中达到最大工作线程数,则可能发生死锁。

在你的情况下,它不是死锁(至少这里发布的代码,它可能是实际代码)。完成需要很长时间。仅仅因为线程池的启发式方法在添加新的工作线程之前等待线程完成。

您可以在开始执行任务之前通过设置线程池的MinThreads和MaxThreads来证明这一点。

ThreadPool.SetMaxThreads(1000, 1000);
ThreadPool.SetMinThreads(1000, 1000);

现在GetDataUsingDataContract即将完成,因为我们已经预先创建了足够的线程。请注意我不推荐这个。这纯粹是为了演示。除非您知道自己在做什么,否则切勿更改最小/最大线程数。

由于没有足够的信息,我们无法提供具体答案。我的建议是你必须利用async功能。不要不必要地阻塞线程。尽可能使用固有的异步操作(不需要任何线程)。例如:数据库调用,Web请求,网络访问等can be done purely asynchronously

我已经谈过ThreadPool的heuristics a little here了。它可以让你了解幕后的内容。