相关疑难解决方法(0)

如何从getter或setter调用异步方法?

在C#中从getter或setter调用异步方法最优雅的方法是什么?

这里有一些伪代码可以帮助解释自己.

async Task<IEnumerable> MyAsyncMethod()
{
    return await DoSomethingAsync();
}

public IEnumerable MyList
{
    get
    {
         //call MyAsyncMethod() here
    }
}
Run Code Online (Sandbox Code Playgroud)

c# async-ctp

189
推荐指数
7
解决办法
10万
查看次数

在C#中创建单项列表的快捷方式

在C#中,是否有内联快捷方式来实例化只包含一个项目的List <T>.

我现在正在做:

new List<string>( new string[] { "title" } ))
Run Code Online (Sandbox Code Playgroud)

在任何地方使用此代码会降低可读性 我曾想过使用这样的实用方法:

public static List<T> SingleItemList<T>( T value )
{
    return (new List<T>( new T[] { value } ));
}
Run Code Online (Sandbox Code Playgroud)

所以我能做到:

SingleItemList("title");
Run Code Online (Sandbox Code Playgroud)

有更短/更清洁的方式吗?

谢谢.

c#

124
推荐指数
8
解决办法
10万
查看次数

避免所有DI反模式需要异步初始化的类型

我有一个Connections需要异步初始化的类型.这种类型的实例被其他几种类型(例如Storage)消耗,每种类型也需要异步初始化(静态,不是每个实例,并且这些初始化也依赖于Connections).最后,我的逻辑类型(例如Logic)使用这些存储实例.目前使用Simple Injector.

我尝试了几种不同的解决方案,但总有一种反模式存在.


显式初始化(​​时间耦合)

我目前使用的解决方案有Temporal Coupling反模式:

public sealed class Connections
{
  Task InitializeAsync();
}

public sealed class Storage : IStorage
{
  public Storage(Connections connections);
  public static Task InitializeAsync(Connections connections);
}

public sealed class Logic
{
  public Logic(IStorage storage);
}

public static class GlobalConfig
{
  public static async Task EnsureInitialized()
  {
    var connections = Container.GetInstance<Connections>();
    await connections.InitializeAsync();
    await Storage.InitializeAsync(connections);
  }
}
Run Code Online (Sandbox Code Playgroud)

我已经将Temporal Coupling封装成一种方法,所以它并没有那么糟糕.但是,它仍然是一个反模式,而不是像我想的那样可维护.


抽象工厂(同步异步)

常见的解决方案是抽象工厂模式.但是,在这种情况下,我们正在处理异步初始化.因此,我可以通过强制初始化同步运行使用抽象工厂,但这会采用同步异步反模式.我真的不喜欢异步同步方法,因为我有几个存储空间,在我当前的代码中,它们都是同时初始化的; 由于这是一个云应用程序,将其更改为串行同步会增加启动时间,并且由于资源消耗,并行同步也不理想.


异步抽象工厂(不正确的抽象工厂用法)

我也可以使用Abstract Factory和异步工厂方法.但是,这种方法存在一个主要问题.正如马克·西曼(Mark …

dependency-injection initialization abstract-factory async-await simple-injector

29
推荐指数
2
解决办法
1484
查看次数

使用Async的延迟加载属性

我已经学会了在我的存储库中延迟加载属性.现在我想这样做,但我还需要从网页加载一些东西(使用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)

然而,视觉工作室告诉我

"修饰符异步对此项无效"

同时在第一行突出显示"新闻"一词.

是否有可能做到这一点?或者我必须编写一个单独的方法?

c# asynchronous

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

Autofac:注册异步工厂方法

TL;DR:Autofac 支持类似 AutoFixture 的fixture.Get()机制吗?

我正在使用 Autofac 并且需要调用异步工厂方法,如下所示:

class AppModel
{
     public static async Task<AppModel> CreateAsync(IDependency x, IDependency2 y)
     { ... }
}
Run Code Online (Sandbox Code Playgroud)

对我来说执行此类方法并由 Autofac 提供参数的最简单方法是什么?即,我希望能够做类似的事情:

Task<AppModel> creationTask = <some autofaccery>(AppModel.CreateAsync);
var appModel = await creationTask();
Run Code Online (Sandbox Code Playgroud)

其中<some autofaccery>表示与ContainerBuilder和/或IContainer和/或某种形式的生成的委托或类似的交互的某种机制,它本质上是简洁的,并且使我无法显式指定工厂方法的参数。即,我想避免像 atm 那样显式解析每个参数 [和/或必须在依赖项发生变化时更新它们]:

var appModel = await AppModel.CreateAsync( 
    container.Resolve<IDependency>(),
    container.Resolve<IDependency2>());
Run Code Online (Sandbox Code Playgroud)

我位于基础设施组件领域,靠近组合根,可能会以编程方式定义组件注册和/或执行其他应限制在此处的肮脏操作。我不介意参与反射,因为它只被调用一次。

关键是我确实需要观察Exception所产生的任何结果Task

Task<T>在很大程度上是一个转移注意力的话题,但重点是,遵循定义同步工厂方法并让 Autofac 完成工作的正常模式不会成功(至少不会直接),即我不能只是改变它到:

     public static AppModel CreateAsync(IDependency x, IDependency2 y)
     { ... } …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous dependency-injection factory-method autofac

5
推荐指数
1
解决办法
2178
查看次数

任务==懒惰?

public Data GetCurrent(Credentials credentials)
{ 
    var data = new Lazy<Data>(() => GetCurrentInternal(credentials));
    try
    {
        return data.Value;
    }
    catch (InvalidOperationException ex)
    {
        throw ex.InnerException;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我将呼叫更改为以下内容:

var data = new Task<Data>(() => GetCurrentInternal(credentials));
Run Code Online (Sandbox Code Playgroud)

有什么变化吗?我宁愿TaskLazy?怎么样Dispose()catch(Exception)

.net c#

3
推荐指数
2
解决办法
1443
查看次数