与方法的接口包含值元组



我有接口:

public Interface Inter1
{
....
Task<(ITestBulk testBulk, bool resultBulk)> GetBulk(int par1, int par2, string par3);
}

然后得到了一些方法:

class MyClass{
internal bool m_resultBulk;
internal async void NewBulk()
{
....
(ITestBulk, m_resultBulk) = await service.GetBulk(1, 2, "ggg");
} 
}

但是找不到m_resultBulk。我做错了什么?

(作为旁注,您的NewBulk方法返回Task否则其调用方无法等待其完成 - 避免启动"触发并忘记"异步逻辑的代码非常重要,因为在异步延续完成后无法安全清理(或正确捕获错误) - 唯一的例外是 WinForms 和 WPF 中的事件处理程序 - 这是因为它们的同步上下文将正确处理任何失败的内容延续。 - 此外,异步方法的名称通常应以...Async后缀结尾)。

无论如何,您的主要问题是您的GetBulk调用站点(应命名为GetBulkAsync)没有正确声明ValueTuple返回本地。

你想要这个:

class MyClass
{
private bool lastNewBulkResult;
internal async Task NewBulkAsync()
{
(ITestBulk testBulk, bool resultBulk) = await this.service.GetBulkAsync( 1, 2, "ggg" ); // Specify `ConfigureAwait` as appropriate too.
this.lastNewBulkResult = resultBulk;
}
}

但是,此代码存在问题:GetBulkAsync之后的延续可能会在任何线程上运行 - 这意味着MyClass的实例状态(即其字段)正在以线程不安全的方式发生突变。解决方案是重新设计您的类以依赖于不可变状态,并通过方法参数和返回值(或异步结果)表示状态的变化,从而完全避免线程安全问题。

关于混合ValueTupleawait

此声明:

(ITestBulk testBulk, bool resultBulk) = await this.service.GetBulkAsync( 1, 2, "ggg" );

相当于这个:

Task<(ITestBulk testBulk, bool resultBulk)> task = this.service.GetBulkAsync( 1, 2, "ggg" );
(ITestBulk testBulk, bool resultBulk) = await task;

也相当于这个:

Task<(ITestBulk testBulk, bool resultBulk)> task = this.service.GetBulkAsync( 1, 2, "ggg" );
(ITestBulk testBulk, bool resultBulk) tupleValue = await task;
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;

或者这个(使用var进行声明端类型推断):

var task = this.service.GetBulkAsync( 1, 2, "ggg" );
var tupleValue = await task;
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;

或者这个:

var tupleValue = await this.service.GetBulkAsync( 1, 2, "ggg" );
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;

在行中

(ITestBulk, m_resultBulk) = await service.GetBulk(1, 2, "ggg");

左侧的元组缺少第一个元组元素的变量名称。 如果您不需要ITestBulk值,则可以使用如下丢弃:

(_, m_resultBulk) = await service.GetBulk(1, 2, "ggg");

如果需要,需要声明一个变量(因为不能在元组中混合声明和解构):

ITestBulk testBulk;
(testBulk, m_resultBulk) = await service.GetBulk(1, 2, "ggg");

最新更新