我被要求将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);
}
我原以为在调试器中单步执行此循环应该会立即返回,而是等待服务调用在返回之前完成。我错过了什么吗?
答案 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:
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);
希望这有帮助