相关疑难解决方法(0)

如何构建一个任务而不启动它?

我想使用这个Task <>构造函数.我似乎无法得到正确的sntax可以有人纠正我的代码.

另外,我是否正确地认为,如果一个任务是以这种方式构建的,那么它是不是已经开始了?

我认为我需要的构造函数:

Task<TResult>(Func<Object, TResult>, Object)
Run Code Online (Sandbox Code Playgroud)

我的代码错误:

参数1:无法从'方法组'转换为' System.Func<object,int>'

static void Main(string[] args)
{
    var t = new Task<int>(GetIntAsync, "3"); //error is on this line
    ...
}

static async Task<int> GetIntAsync(string callerThreadId)
{
    ...
    return someInt;
}
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library async-await

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

是否存在IDictionary的LRU实现?

我想实现一个简单的内存LRU缓存系统,我正在考虑一个基于IDictionary实现的解决方案,它可以处理散列LRU机制.来自java,我有经验LinkedHashMap,可以满足我的需要:我找不到任何类似的.NET解决方案.

有人开发过它或有没有人有这样的经历?

c# caching programming-languages

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

强制C#异步任务是懒惰的吗?

我有一种情况,我有一个特殊工厂创建的对象树.这有点类似于DI容器,但并不完全相同.

对象的创建总是通过构造函数发生,并且对象是不可变的.

在给定的执行中可能不需要对象树的某些部分,应该懒惰地创建.因此构造函数参数应该只是按需创建的工厂.这看起来像是一份工作Lazy.

但是,对象创建可能需要访问慢资源,因此始终是异步的.(对象工厂的创建函数返回一个Task.)这意味着该创建函数Lazy需要是异步的,因此注入的类型需要Lazy<Task<Foo>>.

但我宁愿没有双层包装.我想知道是否有可能强迫一个Task懒惰,即创建一个Task保证在等待之前不执行的东西.据我所知,a Task.Run或者Task.Factory.StartNew可以随时开始执行(例如,如果来自池的线程是空闲的),即使没有什么可以等待它.

public class SomePart
{
  // Factory should create OtherPart immediately, but SlowPart
  // creation should not run until and unless someone actually
  // awaits the task.
  public SomePart(OtherPart eagerPart, Task<SlowPart> lazyPart)
  {
    EagerPart = eagerPart;
    LazyPart = lazyPart;
  }

  public OtherPart EagerPart {get;}
  public Task<SlowPart> LazyPart {get;}
}
Run Code Online (Sandbox Code Playgroud)

.net c# asynchronous .net-core

18
推荐指数
2
解决办法
6395
查看次数

Async threadsafe从MemoryCache获取

我创建了一个MemoryCache在下面使用.NET的异步缓存.这是代码

public async Task<T> GetAsync(string key, Func<Task<T>> populator, TimeSpan expire, object parameters)
{
    if(parameters != null)
        key += JsonConvert.SerializeObject(parameters);

    if(!_cache.Contains(key))
    {
        var data = await populator();
        lock(_cache)
        {
            if(!_cache.Contains(key)) //Check again but locked this time
                _cache.Add(key, data, DateTimeOffset.Now.Add(expire));
        }
    }

    return (T)_cache.Get(key);
}
Run Code Online (Sandbox Code Playgroud)

我认为唯一的缺点是我需要在锁外等待,所以populator不是线程安全的,但是因为await不能驻留在锁内,我想这是最好的方法.我错过了任何陷阱吗?

更新:当antoher线程使缓存无效时,Esers应答的版本也是线程安全的

public async Task<T> GetAsync(string key, Func<Task<T>> populator, TimeSpan expire, object parameters)
{
    if(parameters != null)
        key += JsonConvert.SerializeObject(parameters);

    var lazy = new Lazy<Task<T>>(populator, true);
    _cache.AddOrGetExisting(key, lazy, DateTimeOffset.Now.Add(expire));
    return ((Lazy<Task<T>>) _cache.Get(key)).Value;
}
Run Code Online (Sandbox Code Playgroud)

但它可能会更慢,因为它会创建永远不会执行的Lazy实例,并且它在完全线程安全模式下使用Lazy …

c# thread-safety async-await

16
推荐指数
4
解决办法
7317
查看次数

带有异步初始化的 Lazy&lt;Task&lt;T&gt;&gt;

class Laziness
{
    static string cmdText = null;
    static SqlConnection conn = null;

 
    Lazy<Task<Person>> person =
        new Lazy<Task<Person>>(async () =>      
        {
            using (var cmd = new SqlCommand(cmdText, conn))
            using (var reader = await cmd.ExecuteReaderAsync())
            {
                if (await reader.ReadAsync())
                {
                    string firstName = reader["first_name"].ToString();
                    string lastName = reader["last_name"].ToString();
                    return new Person(firstName, lastName);
                }
            }
            throw new Exception("Failed to fetch Person");
        });

    public async Task<Person> FetchPerson()
    {
        return await person.Value;              
    }
}
Run Code Online (Sandbox Code Playgroud)

Riccardo Terrell 于 2018 年 6 月出版的《.NET 中的并发》一书说道: …

c# asynchronous lazy-evaluation async-await

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

ConcurrentDictionary GetOr添加异步

我想使用诸如GetOrAdda之类的东西ConcurrentDictionary作为Web服务的缓存。该词典有异步版本吗?GetOrAdd将使用发出Web请求HttpClient,因此,如果该词典的某个版本中GetOrAdd是异步的,那就太好了。

为了消除混淆,字典的内容将是对Web服务的调用的响应。

ConcurrentDictionary<string, Response> _cache = new ConcurrentDictionary<string, Response>();



var response = _cache.GetOrAdd("id", (x) => { _httpClient.GetAsync(x).GetAwaiter().GetResponse();} )
Run Code Online (Sandbox Code Playgroud)

.net c# .net-core .net-core-2.2

6
推荐指数
4
解决办法
1183
查看次数

使用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万
查看次数