任务异步混乱
Task Async confusion
有人要求我将 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;
}
我已经在客户端生成了带有"generate asynchronous operations"标志的代理类,我用下面的代码调用服务(服务调用就在最后)
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);
}
我原以为在调试器中单步执行这个循环应该会立即返回,但它会在它之前等待服务调用完成 returns。我错过了什么吗?
修正代码
您必须以不同的方式调用 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);
希望对您有所帮助
您在实现中调用了旧的同步方法。
this._client.ReplicateData(credentialData);
您可以这样调用异步版本:
await this._client.ReplicateDataAsync(credentialData);
如果您的方法签名还不需要 async 修饰符,那么它也需要它。
您似乎使用的是 同步 版本的客户端 API 而不是 异步 版本:
this._client.ReplicateData(credentialData);
我建议不要使用 async over sync anti-pattern,而是使用 API.
的 synchronous 版本
使用 WCF 来 generate a task based operation 您可以等待:
var replicatedData = await _client.ReplicateDataAsync();
有人要求我将 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;
}
我已经在客户端生成了带有"generate asynchronous operations"标志的代理类,我用下面的代码调用服务(服务调用就在最后)
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);
}
我原以为在调试器中单步执行这个循环应该会立即返回,但它会在它之前等待服务调用完成 returns。我错过了什么吗?
修正代码
您必须以不同的方式调用 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);
希望对您有所帮助
您在实现中调用了旧的同步方法。
this._client.ReplicateData(credentialData);
您可以这样调用异步版本:
await this._client.ReplicateDataAsync(credentialData);
如果您的方法签名还不需要 async 修饰符,那么它也需要它。
您似乎使用的是 同步 版本的客户端 API 而不是 异步 版本:
this._client.ReplicateData(credentialData);
我建议不要使用 async over sync anti-pattern,而是使用 API.
的 synchronous 版本使用 WCF 来 generate a task based operation 您可以等待:
var replicatedData = await _client.ReplicateDataAsync();