简介:我想在构造函数中调用异步方法.这可能吗?
详细信息:我有一个调用getwritings()JSON数据的方法.如果我只是调用getwritings()一个async方法并将其放在await左侧,那么一切正常.但是,当我LongListView在我的页面中创建一个并尝试填充它时,我发现这getWritings()是令人惊讶的返回null而且LongListView是空的.
为了解决这个问题,我尝试更改getWritings()to 的返回类型,Task<List<Writing>>然后在构造函数中检索结果getWritings().Result.但是,这样做最终会阻止UI线程.
public partial class Page2 : PhoneApplicationPage
{
    List<Writing> writings;
    public Page2()
    {
        InitializeComponent();
        getWritings();
    }
    private async void getWritings()
    {
        string jsonData = await JsonDataManager.GetJsonAsync("1");
        JObject obj = JObject.Parse(jsonData);
        JArray array = (JArray)obj["posts"];
        for (int i = 0; i < array.Count; i++)
        {
            Writing writing = new Writing();
            writing.content = JsonDataManager.JsonParse(array, …c# constructor async-await windows-phone-8 visual-studio-2013
我试图理解为什么ASP.Net应用程序中的异步void方法可能导致以下异常,而async Task似乎不会:
System.InvalidOperationException: An asynchronous module or handler 
completed while an asynchronous operation was still pending
我对.NET中的异步世界相对较新,但我觉得我试图通过一些现有资源来运行这个,包括以下所有内容:
从这些资源中,我了解最佳做法是通常返回Task并避免异步void.我也理解async void会在调用方法时增加未完成操作的数量,并在完成时减少它.这听起来至少是我问题答案的一部分.但是,我遗漏的是当我返回Task时会发生什么,以及为什么这样做会让事情变得"有效".
这是一个人为的例子来进一步说明我的问题:
public class HomeController : AsyncController
{
    // This method will work fine
    public async Task<ActionResult> ThisPageWillLoad()
    {
        // Do not await the task since it is meant to be fire and forget
        var task = this.FireAndForgetTask();
        return await Task.FromResult(this.View("Index"));
    }
    private async Task FireAndForgetTask()
    {
        var task = Task.Delay(TimeSpan.FromSeconds(3));
        await task;
    }
    // This …我的视图包含一个ListView,它显示来自互联网的一些数据,我创建了一个异步方法来加载数据并在我的viewmodel的构造函数中调用该方法.它有一个警告提示我现在使用await关键字.
在构造函数中异步加载数据的任何其他解决方案?
我只是想知道async/await在DI期间是否有可能.
执行以下操作,DI无法解析我的服务.
services.AddScoped(async provider => 
{
  var client = new MyClient();
  await client.ConnectAsync();
  return client;
});
以下作品完美无缺.
services.AddScoped(provider => 
{
  var client = new MyClient();
  client.ConnectAsync().Wait();
  return client;
});
c# dependency-injection async-await asp.net-core-mvc asp.net-core-webapi
我有一个Xamarin.Forms应用程序,在我的App类中使用此代码(是的,这只是一个演示问题的示例):
    public App()
    {
        BlobCache.ApplicationName = "MyApp";
        BlobCache.EnsureInitialized();
        // The root page of your application
        MainPage = GetMainPage();
    }
    public object BlockingGetExternalUser()
    {
        return GetExternalUser().Result;
    }
    private async Task<object> GetExternalUser()
    {
        try
        {
            return await BlobCache.LocalMachine.GetObject<object>("user");
        }
        catch (KeyNotFoundException)
        {
            return null;
        }
    }
密钥"用户"不存在,所以我希望得到一个KeyNotFoundException.但是我从来没有看到过抛出这个异常.相反,它只是"挂起",永远不会从await GetObject调用返回.
我在Android 5.0手机上运行此功能.
任何想法如何解决这一问题?我做了一些根本错误的事吗?
更新:旁注:不是立即尝试GetObject,而是可以尝试检查密钥是否实际存在于缓存中,然后才从缓存中检索它.但是,如果我没有弄错的话,除了调用GetObject并捕获异常之外没有其他方法可以进行检查,就像上面的示例一样.对于一个人只想知道项目是否存在的情况,这似乎并不理想.也许在Akavache中使用"存在()"方法会很好吗?或许我错过了什么?
Update2:更改示例以在构造函数中不使用async方法.只是为了证明这不是问题.
Update3:从构造函数中删除调用.当我从代码中的任何地方调用BlockingGetExternalUser时,await仍会挂起.
这似乎与具有相同错误的数百个其他问题重复.我看了他们所有人,发现他们是无关的.
我正在制作一个小笔记应用程序,我正在尝试从目录中读取文件.在MSDN示例之后,我有以下代码,但它给出了一个错误:
错误1修饰符'async'对此项目无效C:\ Users\Jase\documents\visual studio 2012\Projects\AppNameHere\AppNameHere\DataModel\AppNameHereDataSource.cs 192 9 AppNameHere
    async public NotesDataSource()
    {
        StorageFolder documentsFolder = KnownFolders.DocumentsLibrary;
        StringBuilder outputText = new StringBuilder();
        IReadOnlyList<StorageFile> fileList =
            await documentsFolder.GetFilesAsync();
        outputText.AppendLine("Files:");
        foreach (StorageFile file in fileList)
        {
            if (file.FileType == "txt")
            {
                outputText.Append(file.Name + "\n");
            }
        }
        // lots of irrelevant code removed.
    }
谢谢!
目前我正在使用 c# 开发一个通用应用程序。
在应用程序中,我使用 sqlite 作为数据库,正如您现在可能的那样,它具有异步方法。
我有一个带有一些空属性的类,我将使用从数据库中获取的数据填充它们,但它应该完全在类构造函数中完成。
问题是不允许使用异步方法,所以我尝试创建一个新的异步方法并使用 sqlite 方法并在其中填充属性以在构造函数中同步调用它,但正如预期的那样它不能很好地工作。
如何在类构造函数中使用异步方法从数据库获取数据并在类构造函数方法中填充类属性?
更新:请注意,我不是在问是否可以完成,我想在构建类时使用来自 db 的数据来初始化我的类变量
我需要从 mvc 应用程序调用第三方异步方法。此异步方法的名称是 ForceClient.QueryAsync。它来自一个开源项目:https ://github.com/developerforce/Force.com-Toolkit-for-NET/ 。
下面工作正常,当进程处于 mvc 的 View 阶段时, model.Opportunity 包含预期信息:
public async Task<ActionResult> MyController(string Id) {
    . . . .
    MyModel model = new MyModel();
    var client = new ForceClient(instanceUrl, accessToken, apiVersion);
    var qry = await client.QueryAsync<MyModel.SFOpportunity>(
            "SELECT Name, StageName FROM Opportunity where  Id='" + Id + "'");
    model.Opportunity = qry.Records.FirstOrDefault();
    . . . .
return View(viewName, myModel);
}
但下面不起作用。当流程处于View阶段时,model.Opportunity为null。我做了一些调试,发现流程是这样的:
1)步骤1
2)步骤2
3)在View阶段。此时 model.Opportunity 为 null,我需要将其填充。
4)步骤3。
public async Task<ActionResult> MyController(string Id) {
    . . . …我已经基于Split Page示例应用程序创建了一个Windows 8 Metro应用程序.但是,在示例应用程序中,数据在构造函数中同步加载.我正在访问文本文件,因此需要异步加载数据.构造函数如下所示:
    public MyDataSource()
    {
        DataLoaded = false;
        LoadData();
    }
LoadData()是一种填充数据模型的异步方法.这工作正常,并在加载数据时显示数据(这是我想要的行为).当我尝试测试挂起并终止时,会出现问题.问题是恢复有可能在填充之前尝试访问数据模型:
    public static MyDataGroup GetGroup(string uniqueId)
    {
        // If the data hasn't been loaded yet then what?
        if (_myDataSource == null)
        {
        // Where app has been suspended and terminated there is no data available yet
        }
        // Simple linear search is acceptable for small data sets
        var matches = _myDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
        if (matches.Count() == 1) return matches.First();
        return null;
    }
我可以通过更改要调用的构造函数来解决此问题LoadData().Wait,但这意味着应用程序会锁定UI线程.我认为我需要的是一种获取恢复代码的方法,GetGroup以等待数据加载而不锁定UI线程.这是可行的还是可取的,如果是这样,怎么样? …
我有一个关于我在构造函数中调用的异步方法的问题以及如何解决或者是否有一个好的解决方法,这是一个示例
public Constructor()
{
 Value = PopulateValueFromDB(); //async method
 CalculateInDB(); // async method
}
public async Task<string> PopulateValueFromDB()
{
 ... do some async calls
 return await ...
}
public async Task CalculateInDB()
{
 ...
 return await ...
}
基本上在构造函数中我有一个错误,因为我不能在那里使用等待,并且我不能使其异步。
对于CalculateInDB,我可以使其返回void,然后我用它解决问题,尽管我在某处读到返回void并不是很好的解决方案。
关于 PopulateVlaue 方法......我必须返回一些东西......
那么,有没有一种解决办法,让我不应该使用这些方法并使它们同步而不是异步?
我有一个使用 Prism 的 WPF 应用程序,并且我发现异步方法存在额外行为。
我有一个带有这样的异步方法的类
public class ConfigurationManager(){
    public async Task<IList<T>> LoadConfigurationAsync<T>(){
        Tuple<IList<T>, bool> tuple = await LoadConfigurationItemsAsync();
        return tuple.Item1;
    }
    private async Task<Tuple<IList<T>, bool>> LoadConfigurationItemsAsync<T>(){
        await Task.Run(()  => 
        {
        });
        return new Tuple<IList<T>, bool>(configList.list, succes);
    }
}
我需要以同步形式调用它们,因为我需要 ViewModelManager 的构造函数中的结果,并且我尝试使用 Result,因为这是以同步方式获取结果的方法之一。
public class ViewModelManager{
    private readonly ConfigurationManager _configManager;
    private void LoadConfiguration(){
        var config = _configManager.LoadConfigurationAsync().Result;
    }
}
令我惊讶的是,这导致应用程序在 Result 调用中被阻止,我知道 Result 被阻止,但并非总是如此,方法的返回行永远不会被执行。我尝试使用它来调用它Task.Run并且它有效
private void LoadConfiguration(){
    var config = Task.Run(() => _configManager.LoadConfigurationAsync()).Result;
}
我不知道这里发生了什么,也不知道为什么调用结果会导致应用程序被阻止以及为什么使用Task.Run它有效。这就像调用两个任务,因为该方法已经返回一个Task …
c# ×11
async-await ×7
asynchronous ×3
.net ×2
constructor ×2
wpf ×2
.net-4.5 ×1
akavache ×1
android ×1
asp.net ×1
io ×1
methods ×1
prism ×1
sqlite ×1
windows-8 ×1