任务异步混乱

时间:2015-02-13 14:51:00

标签: c# wcf asynchronous

我被要求将WCF服务调用从同步转换为异步,但调用似乎仍在同步运行。我做错了什么?

这是我的服务合同

[ServiceContract]
public interface ICredentialReplication
{
    /// <summary>
    /// Updates the store database with credential data
    /// </summary>
    /// <param name="credentials">the credential data to update</param>
    [OperationContract]
    Task ReplicateDataAsync(CredentialDataList credentials);

这是我的实施

/// <summary>
    /// Copy the credential data to the stores
    /// </summary>
    /// <param name="credentials">The credential data to copy</param>
    public async Task ReplicateDataAsync(CredentialDataList credentials)
    {
        var task = Task.Factory.StartNew(() => UpdateData(credentials));
        await task;  
    }

我已经使用&#34;生成异步操作&#34;生成了代理类。在客户端设置标志,我使用以下代码调用服务(服务调用在最后)

 foreach (var store in storedic)
            {
                // call the replication service for that store                    
                CredentialDataList credentialData = new CredentialDataList();
                List<CredentialData> credentialList = new List<CredentialData>();

                foreach (var payroll in store)
                {
                    CredentialData cred = this.ExtractCredentialData(data, pinData, payroll);
                    credentialList.Add(cred);                       
                }

                credentialData.CredentialList = credentialList.ToArray();
                credentialData.PermissionList = permDataList;
                credentialData.PermissionTypeList = permTypeDataList;   

                // then call the service
                this._client.ReplicateData(credentialData);     
            }               

我原以为在调试器中单步执行此循环应该会立即返回,而是等待服务调用在返回之前完成。我错过了什么吗?

3 个答案:

答案 0 :(得分:1)

您正在实施中调用旧的同步方法。

this._client.ReplicateData(credentialData);

您可以像这样调用异步版本:

await this._client.ReplicateDataAsync(credentialData);

如果没有async修饰符,您的方法签名也需要。

答案 1 :(得分:1)

您似乎正在使用客户端API的同步版本,而不是异步版本:

this._client.ReplicateData(credentialData); 

而不是使用async over sync anti-pattern,我建议使用API​​的同步版本。

使用WCF到你可以等待的generate a task based operation

Wcf settings

var replicatedData =  await _client.ReplicateDataAsync();

答案 2 :(得分:0)

修复代码

您必须以不同的方式调用WCF服务方法:

var task = Task.Factory.StartNew(() => this._client.ReplicateData(credentialData));

或使用魔法

或者另一种可能性是保持服务的相同代码,并且只是将客户端配置为异步调用服务。可以通过在visual studio中更改服务引用的属性来完成此配置。配置完成后,您只需使用名为<MethodName>Async()的方法即可。服务方面无需更改。

[编辑]

您的代码在以下情况后应如何显示:

服务合同:

[ServiceContract]
public interface ICredentialReplication
{
    /// <summary>
    /// Updates the store database with credential data
    /// </summary>
    /// <param name="credentials">the credential data to update</param>
    [OperationContract]
    void ReplicateData(CredentialDataList credentials);
}

<强>实施

/// <summary>
/// Copy the credential data to the stores
/// </summary>
/// <param name="credentials">The credential data to copy</param>
public void ReplicateData(CredentialDataList credentials)
{
    UpdateData(credentials); 
}

服务消费:

this._client.ReplicateDataAsync(credentialData);

希望这有帮助