这是示例:
if(value != ageValue) {
ageValue = value;
}
Run Code Online (Sandbox Code Playgroud)
我的意思是,如果我们将一个变量的值分配给另一个变量,为什么还要检查它们是否具有相同的值?
这让我感到困惑。这里是更广泛的上下文:
private double ageValue;
public double Age {
get {
return ageValue;
}
set {
if(value != ageValue) {
ageValue = value;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我的WPF应用程序被组织为TabControl,每个选项卡包含不同的屏幕.
一个TabItem绑定到需要一点时间才能加载的数据.由于此TabItem表示用户可能很少使用的屏幕,因此我希望在用户选择选项卡之前不加载数据.
我怎样才能做到这一点?
可能重复:
如何从getter或setter调用异步方法?
我正在尝试实现一个在其中使用Sqlite等待的属性:
public int ID {
get
{
if (_id != null)
{
return _id;
}
if (string.IsNullOrEmpty(ImageName))
{
return -1;
}
var query = CurrentConnection.Table<Image>().Where(i => i.ImageName == ImageName);
var result = await query.ToListAsync();
...other code
Run Code Online (Sandbox Code Playgroud)
但是,由于属性未设置为等待(尝试过,不起作用),我不能在属性中使用await.
除了使用方法而不是属性之外,还有什么方法可以解决这个问题?
更新:@usr指出我错误地认为Lazy<T>
默认的线程安全模式是LazyThreadSafetyMode.PublicationOnly
......
我想懒洋洋地通过async
工厂方法计算一个值(即它返回Task<T>
)并在成功时缓存它.在例外情况下,我想让我可以使用它.我不然而,要堕入了异常缓存的行为是Lazy<T>
在其默认模式(LazyThreadSafetyMode.ExecutionAndPublication
)
异常缓存:使用工厂方法时,会缓存异常.也就是说,如果工厂方法在线程第一次尝试访问Lazy对象的Value属性时抛出异常,则每次后续尝试都会抛出相同的异常.这确保了对Value属性的每次调用都会产生相同的结果,并避免在不同的线程获得不同结果时可能出现的细微错误.懒惰代表一个实际的T,否则它将在某些早期点(通常在启动期间)初始化.在那个早期点失败通常是致命的.如果存在可恢复故障的可能性,我们建议您将重试逻辑构建到初始化例程(在本例中为工厂方法),就像您不使用延迟初始化一样.
Stephen Toub的AsyncLazy
课程和写作似乎恰到好处:
public class AsyncLazy<T> : Lazy<Task<T>>
{
public AsyncLazy(Func<Task<T>> taskFactory) :
base(() => Task.Factory.StartNew(() => taskFactory()).Unwrap())
{ }
public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); }
}
Run Code Online (Sandbox Code Playgroud)
然而,这实际上与默认行为相同Lazy<T>
- 如果出现问题,则不会重试.
我正在寻找一个Task<T>
兼容的等价物Lazy<T>(Func<T>, LazyThreadSafetyMode.PublicationOnly)
,即它应该按照指定的行为: -
锁定的替代方法在某些情况下,您可能希望避免Lazy对象的默认锁定行为的开销.在极少数情况下,可能存在死锁的可能性.在这种情况下,您可以使用Lazy(LazyThreadSafetyMode)或Lazy(Func,LazyThreadSafetyMode)构造函数,并指定LazyThreadSafetyMode.PublicationOnly.如果线程同时调用Value属性,这使Lazy对象能够在多个线程中的每个线程上创建一个延迟初始化对象的副本.Lazy对象确保所有线程使用延迟初始化对象的相同实例并丢弃未使用的实例.因此,降低锁定开销的成本是您的程序有时可能会创建并丢弃昂贵对象的额外副本.在大多数情况下,这不太可能.Lazy(LazyThreadSafetyMode)和Lazy(Func,LazyThreadSafetyMode)构造函数的示例演示了此行为.
重要
指定PublicationOnly时,即使指定了工厂方法,也不会缓存异常.
是否有任何FCL Nito.AsyncEx
或类似的结构可能适合这里?如果没有这个,任何人都可以看到一种优雅的方式来控制"尝试进行中"位(我很好,每个调用者以与Lazy<T>(
... 相同的方式进行自己的尝试(LazyThreadSafetyMode.PublicationOnly)
)并且仍然具有该缓存管理封装整齐?
Dispatcher
.NET Core是否存在类似的东西?
我需要在 .NET Core 中创建一个线程,并且能够发送要在该线程上调用的操作。另外,我希望能够使用一个TaskScheduler
可以用于async/await
东西的东西。
这在某处存在吗?
我已经学会了在我的存储库中延迟加载属性.现在我想这样做,但我还需要从网页加载一些东西(使用Httpclient),这意味着我的属性将是异步的.
public async Task<List<NewsModel>> News
{
get
{
if (_news == null)
{
CacheProvider cache = new CacheProvider();
object cachedNews = cache.Get("news");
if (cachedNews == null)
{
var client = new HttpClient();
// await HttpResponse
}
}
return _news;
}
set
{
_news = value;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,视觉工作室告诉我
"修饰符异步对此项无效"
同时在第一行突出显示"新闻"一词.
是否有可能做到这一点?或者我必须编写一个单独的方法?
我需要等待属性setter方法的异步函数.
public String testFunc()
{
get
{
}
set
{
//Await Call to the async func <asyncFunc()>
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我们不应该制作异步属性,所以最佳方法是什么.
我有一个问题,想知道异步函数需要遵循的最佳实践。我的视图模型中有两个函数,它们是从属性的设置器中调用的。这两个函数是 async void,但我们希望将它们转换为 async of task,因为 async void 是不良代码的味道。但 setter 属性不允许我们等待。所以我想知道我应该从哪里调用这两个函数,我们也不想从构造函数中执行此操作,因为我们也不能等待函数,而构造函数不是用于此目的。我只想知道避免从属性调用异步任务函数的最佳实践。我想设置并填充属性更改的数据,因此我们从属性调用异步函数。
c# ×7
.net ×5
async-await ×3
asynchronous ×3
.net-core ×2
c#-5.0 ×1
if-statement ×1
task ×1
windows ×1
wpf ×1