前言:我正在寻找解释,而不仅仅是解决方案.我已经知道了解决方案.
尽管花了几天时间研究MSDN关于基于任务的异步模式(TAP),异步和等待的文章,但我仍然对一些更精细的细节感到困惑.
我正在为Windows Store应用程序编写一个记录器,我想支持异步和同步日志记录.异步方法遵循TAP,同步方法应该隐藏所有这些,并且看起来像普通方法一样工作.
这是异步日志记录的核心方法:
private async Task WriteToLogAsync(string text)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("log.log",
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, text,
Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
Run Code Online (Sandbox Code Playgroud)
现在相应的同步方法......
版本1:
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Run Code Online (Sandbox Code Playgroud)
这看起来是正确的,但它不起作用.整个程序永远冻结.
版本2:
嗯..也许任务没有开始?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Run Code Online (Sandbox Code Playgroud)
这引发了 InvalidOperationException: Start may not be called on a promise-style task.
版本3:
嗯.. Task.RunSynchronously听起来很有希望.
private void WriteToLog(string text)
{
Task task = …Run Code Online (Sandbox Code Playgroud) .net c# task-parallel-library async-await windows-store-apps
我有一个Silverlight项目,我试图在构造函数中填充一些数据:
public class ViewModel
{
public ObservableCollection<TData> Data { get; set; }
async public ViewModel()
{
Data = await GetDataTask();
}
public Task<ObservableCollection<TData>> GetDataTask()
{
Task<ObservableCollection<TData>> task;
//Create a task which represents getting the data
return task;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我收到一个错误:
修饰符
async对此项目无效
当然,如果我在标准方法中包装并从构造函数中调用它:
public async void Foo()
{
Data = await GetDataTask();
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.同样,如果我使用旧的由内而外的方式
GetData().ContinueWith(t => Data = t.Result);
Run Code Online (Sandbox Code Playgroud)
这也有效.我只是想知道为什么我们不能await直接在构造函数内调用.可能有很多(甚至是明显的)边缘情况和反对它的理由,我只是想不出来.我也在寻找解释,但似乎找不到任何解释.
我正在使用SQLite.NET PCL库来获取我的WinRT项目,
SQliteAsyncConnection该类提供了经典SQLiteConnection方法的异步版本.但是,在项目的Github页面上,陈述如下:
请注意,使用的
Task.Run模式SQLiteAsyncConnection可以被视为反模式(库不应该提供异步方法,除非它们是真正的异步).维护此类是为了向后兼容,也适用于异步隔离很方便的用例
为什么Task.Run在这种情况下使用被认为是反模式?这允许开发人员实现他所需的目标 - 在应用程序保持响应用户输入的同时在单独的线程上运行数据库访问代码.Task.Run每次手动编写代码片段并不完全使用该类的异步版本会更好吗?
这种模式的潜在问题和挫折是什么?