相关疑难解决方法(0)

构造函数可以异步吗?

我有一个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直接在构造函数内调用.可能有很多(甚至是明显的)边缘情况和反对它的理由,我只是想不出来.我也在寻找解释,但似乎找不到任何解释.

c# constructor async-await

262
推荐指数
3
解决办法
13万
查看次数

导致死锁的异步/等待示例

我发现了一些使用c#async/ awaitkeywords的异步编程的最佳实践(我是c#5.0的新手).

给出的建议之一是:

稳定性:了解同步上下文

...某些同步上下文是不可重入和单线程的.这意味着在给定时间内只能在上下文中执行一个工作单元.一个例子是Windows UI线程或ASP.NET请求上下文.在这些单线程同步上下文中,很容易使自己陷入僵局.如果从单线程上下文中生成任务,然后在上下文中等待该任务,则等待代码可能会阻止后台任务.

public ActionResult ActionAsync()
{
    // DEADLOCK: this blocks on the async task
    var data = GetDataAsync().Result;

    return View(data);
}

private async Task<string> GetDataAsync()
{
    // a very simple async method
    var result = await MyWebService.GetDataAsync();
    return result.ToString();
}
Run Code Online (Sandbox Code Playgroud)

如果我自己尝试剖析它,主线程会产生一个新线程MyWebService.GetDataAsync();,但由于主线程在那里等待,它等待结果GetDataAsync().Result.同时,说数据准备好了.为什么主线程不继续它的延续逻辑并从中返回字符串结果GetDataAsync()

有人可以解释一下为什么上面的例子中存在死锁吗?我完全不知道问题是什么......

c# deadlock task-parallel-library async-await c#-5.0

87
推荐指数
3
解决办法
4万
查看次数

Azure 表存储 - CreateTableIfNotExists 挂起 - 以前工作

我一直在努力让一些代码在新机器上工作。我以为我终于让它工作了,但是现在当我运行它时,代码在尝试创建表存储时挂起(或者实际上获得了对它,因为它已经存在)......我知道必须确保它一直是异步的并且这段代码正在工作......我现在已经改变了它以尝试改进它并让它在这台机器上工作,但有些不对劲......所以在 Repo 的构造函数中我这样做......

public LdsRepo() 
    {

        if (!GetTableRef("licensedatesummary").Result)
        {
            throw new Exception("It broke!");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的 GetTableReference 方法(在基类上)是这样的......

protected async Task<bool>  GetTableRef(string tableRef)
    {
        try
        {
            if (string.IsNullOrEmpty(StorageAccountName) || string.IsNullOrEmpty(AuthKey))
            {
                throw new ArgumentNullException(nameof(tableRef),
                    "storageaccountname or authk are not set in the config");
            }
            if (_tableClient == null)
                _tableClient =
                    new CloudStorageAccount(new StorageCredentials(StorageAccountName, AuthKey), true)
                        .CreateCloudTableClient();
            if (_table == null)
            {
                // Create the CloudTable object that represents the referenced table.
                _table = _tableClient.GetTableReference(tableRef);
                var x =  _table.CreateIfNotExistsAsync();
                return await …
Run Code Online (Sandbox Code Playgroud)

azure azure-storage asp.net-web-api

2
推荐指数
1
解决办法
916
查看次数

.Result()使方法挂起时,如何在构造函数中使用异步方法?

当Xamarin.Forms项目中出现页面时,我有一个AppearingCommand调用,该页面最终执行以下sqlite-net-pcl行:(我已经有一种应对加载时间的机制)

AppearingCommand = new Command( async() => {
    //...
    var data = await db.Table<PlantCategory>().ToListAsync();
    //...
}
Run Code Online (Sandbox Code Playgroud)

我想将此方法移到构造函数中,但我不能这样做,因为如果同步执行它会挂起:

ctor() {
    //...
    var data = db.Table<PlantCategory>().ToListAsync().Result;
    //...
}
Run Code Online (Sandbox Code Playgroud)

该行永远不会返回(我猜是由于死锁或其他原因)。如果要在构造函数中执行此行,我还有什么其他选择?

c# sqlite mvvm xamarin.forms sqlite-net-pcl

0
推荐指数
1
解决办法
54
查看次数