ThreadStatic—WCF方法调用是否以独占方式在单个线程上执行?

ThreadStatic—WCF方法调用是否以独占方式在单个线程上执行?,wcf,threadstatic,Wcf,Threadstatic,我们的WCF服务引用的一个库使用ThreadStatic变量。服务方法在每次调用开始时设置其值。我想知道这是否安全——换句话说,我们能保证整个调用只使用一个线程吗?或者,调用是否可能在一个工作线程上开始,在另一个工作线程上结束?或者工作线程是否可以交换到不同的方法调用,然后再返回 我们使用默认值ConcurrencyMode.Single和InstanceContextMode.PerSession 编辑 到目前为止,我能找到的唯一信息是这篇博文,其中指出一个调用可以由多个线程处理: 这家伙说

我们的WCF服务引用的一个库使用ThreadStatic变量。服务方法在每次调用开始时设置其值。我想知道这是否安全——换句话说,我们能保证整个调用只使用一个线程吗?或者,调用是否可能在一个工作线程上开始,在另一个工作线程上结束?或者工作线程是否可以交换到不同的方法调用,然后再返回

我们使用默认值ConcurrencyMode.Single和InstanceContextMode.PerSession

编辑

到目前为止,我能找到的唯一信息是这篇博文,其中指出一个调用可以由多个线程处理:

这家伙说得对吗?是否有来自Microsoft的明确信息?

我有保存问题。 要调查我是否启动了负载测试并开始测试GetRolesForUser:

public override bool IsUserInRole(string username, string roleName)
    {
        object stub = new object();
        bool res;
        lock(stub)
        {
            RoleProviderCount++;
            ThreadId = Thread.CurrentThread.ManagedThreadId;
            res = GetRolesForUser(username).Contains(roleName);
        }
        return res;
    }
这是我的日志:

Timestamp: 06.11.2012 13:55:03 Message:  ServiceCalls count 1; RoleProvider count 1 Thread Id 9 
Timestamp: 06.11.2012 14:00:22 Message:  ServiceCalls count 1; RoleProvider count 1 Thread Id 9 
Timestamp: 07.11.2012 5:30:38 Message:  ServiceCalls count 1; RoleProvider count 1 Thread Id 11 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:58 Message:  ServiceCalls count 1; RoleProvider count 4 Thread Id 27 
Timestamp: 07.11.2012 5:31:59 Message:  ServiceCalls count 1; RoleProvider count 5 Thread Id 22 
Timestamp: 07.11.2012 5:31:59 Message:  ServiceCalls count 1; RoleProvider count 8 Thread Id 26 
Timestamp: 07.11.2012 5:31:59 Message:  ServiceCalls count 1; RoleProvider count 8 Thread Id 26 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 10 Thread Id 23 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 11 Thread Id 29 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 12 Thread Id 22 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 13 Thread Id 27 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 14 Thread Id 24 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 15 Thread Id 30 
Timestamp: 07.11.2012 5:32:00 Message:  ServiceCalls count 1; RoleProvider count 16 Thread Id 26 
Timestamp: 07.11.2012 5:32:01 Message:  ServiceCalls count 1; RoleProvider count 17 Thread Id 11
Timestamp: 07.11.2012 5:32:01 Message:  ServiceCalls count 1; RoleProvider count 18 Thread Id 23
Timestamp: 07.11.2012 5:32:01 Message:  ServiceCalls count 1; RoleProvider count 20 Thread Id 26
Timestamp: 07.11.2012 5:32:01 Message:  ServiceCalls count 1; RoleProvider count 20 Thread Id 26
Timestamp: 07.11.2012 5:32:01 Message:  ServiceCalls count 1; RoleProvider count 21 Thread Id 24
所以,RoleProvider方法是从同一线程调用的。
(WCF服务配置实例模式PerCall,并发多个)

您所说的一个请求可以在多个请求之间传递的现象称为“线程敏捷性”

简单的回答是不,您不能保证给定的请求将由单个线程处理

请参见此处接受的答案:


*这是IIS托管的WCF的情况,我的一个同事对此作出了回应:


你提到的“这个家伙”肯定是错的。这是不可能的 要在实际线程执行期间更改的线程 服务方式。这适用于任何方法,与WCF无关

可以创建一个异步调用,然后在 另一种方法/线程;但这并不是什么特别的事情:

我当然会非常高兴 有兴趣听听线程敏捷性是否与 方法调用交换线程…我们谈论的是托管线程 在这里,Microsoft没有理由更改线程id。 CallContext是Microsoft提供的一项功能,您可以 如果执行异步调用,则存储状态

有可能 实例上下文使用不同的线程来实例化 服务,而不是执行该方法–尽管如果您使用PerCall,这将 不会发生。你真的在使用会话吗;如果不是,你应该换一个 去珀索尔。同一个系统中可能存在不同的调用 会话将使用不同的线程



似乎有道理。有什么意见吗?

如果您不确定是否可以始终使用CallContext类:


如果线程发生了更改,ThreadStatic将无法工作,而逻辑调用上下文将在.NET中传递,即使您将创建自己的新线程/任务。

答案可能在并发多线程的实现内部?也许这篇文章可以帮助你,你的回答让我困惑。您是否可以添加更多解释和/或更多代码来显示您的日志文件如何回答此问题?以下是关于[ThreadStatic属性如何工作][1][1]的一个很好的解释:我希望您是对的,但对于赏金,我正在寻找明确说明此类问题的官方WCF文档。你知道吗?那真是太棒了——我从来都不知道。我不知道重构是一种选择。如果您可以选择重写使用ThreadStatic的代码,为什么不正确编写并使用OperationContext呢?如果您需要使用消息检查器,那么