4es*_*est 1 c# tuples interface task async-await
我有界面:
public Interface Inter1
{
....
Task<(ITestBulk testBulk, bool resultBulk)> GetBulk(int par1, int par2, string par3);
}
Run Code Online (Sandbox Code Playgroud)
然后得到了一些方法:
class MyClass{
internal bool m_resultBulk;
internal async void NewBulk()
{
....
(ITestBulk, m_resultBulk) = await service.GetBulk(1, 2, "ggg");
}
}
Run Code Online (Sandbox Code Playgroud)
但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;
}
}
Run Code Online (Sandbox Code Playgroud)
然而这段代码有问题: after 的延续GetBulkAsync可能会在任何线程上运行 - 这意味着你的实例状态(即它的字段)正在以线程不安全的MyClass方式发生变化。解决方案是重新设计类以依赖不可变状态并通过方法参数和返回值(或异步结果)表示状态变化,从而完全避免线程安全问题。
ValueTuple和await:这个说法:
(ITestBulk testBulk, bool resultBulk) = await this.service.GetBulkAsync( 1, 2, "ggg" );
Run Code Online (Sandbox Code Playgroud)
相当于这样:
Task<(ITestBulk testBulk, bool resultBulk)> task = this.service.GetBulkAsync( 1, 2, "ggg" );
(ITestBulk testBulk, bool resultBulk) = await task;
Run Code Online (Sandbox Code Playgroud)
并且也相当于这样:
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;
Run Code Online (Sandbox Code Playgroud)
或者这个(用于var声明端类型推断):
var task = this.service.GetBulkAsync( 1, 2, "ggg" );
var tupleValue = await task;
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;
Run Code Online (Sandbox Code Playgroud)
或这个:
var tupleValue = await this.service.GetBulkAsync( 1, 2, "ggg" );
ITestBulk testBulk = tupleValue.testBulk;
bool resultBulk = tupleValue.resultBulk;
Run Code Online (Sandbox Code Playgroud)