小编The*_*ias的帖子

如何使用 C#8 IAsyncEnumerable<T> 异步枚举并行运行的任务

如果可能,我想为并行启动的任务创建一个异步枚举器。所以第一个完成的是枚举的第一个元素,第二个完成的是枚举的第二个元素,依此类推。

public static async IAsyncEnumerable<T> ParallelEnumerateAsync(this IEnumerable<Task<T>> coldAsyncTasks)
{
    // ... 
}
Run Code Online (Sandbox Code Playgroud)

我打赌有一种使用ContinueWith和 a 的方法Queue<T>,但我并不完全相信自己会实现它。

c# asynchronous task-parallel-library async-await iasyncenumerable

8
推荐指数
2
解决办法
5847
查看次数

Parallel.ForEachAsync 是否可以替代普通的 for 循环 + 附加到任务列表 (async wait Task.Run)+ WhenAll?

假设我想发出并行 API post 请求。

在 for 循环中,我可以将 http post 调用附加到任务列表中(使用 Task.Run 调用的每个任务),然后等待所有任务完成使用await Task.WhenAll. 因此,在等待网络请求完成时,控制权将交给调用者。实际上,API 请求将并行发出。

同样,我可以使用Parallel.ForEachAsync它将自动执行WhenAll并将控制权返回给调用者。所以我想问是否ForEachAsync可以替换普通的 for 循环列表(async wait Task.Run)和WhenAll

c# asynchronous async-await parallel.foreachasync

8
推荐指数
1
解决办法
5021
查看次数

如何在遵守一些约束的同时生成数字序列?

在遵守一系列约束的同时,我需要生成从0到999999(不重复)的所有可能的数字(整数)。

为了更好地理解要求,请想象每个数字由2位数字的前缀和4位数字的后缀组成。就像000000被读为00-0000和999999被读为99-9999。现在到规则:

  • 前缀必须是随机顺序
  • 后缀必须按随机顺序排列,同时确保序列中的每个10k数字都具有从0000到9999的所有数字。
  • 给定种子,必须能够以相同的顺序再次生成数字。
  • 并不是真正的要求,但是如果使用Linq完成,那就太好了。

到目前为止,我已经写了一些满足所有要求的代码,但第一个除外:

var seed = 102111;
var rnd = new Random(seed);
var prefix = Enumerable.Range(0, 100).OrderBy(p => rnd.Next());
var suffix = Enumerable.Range(0, 10000).OrderBy(s => rnd.Next());
var result = from p in prefix
                from s in suffix
                select p.ToString("d2") + s.ToString("d4");

foreach(var entry in result)
{
    Console.WriteLine(entry);
}
Run Code Online (Sandbox Code Playgroud)

使用这个我可以使用相同的种子来重现序列,前10000个数字的所有数字都从0000到9999,第二个10k等等,但是前缀并不是真正随机的,因为每个10k组都具有相同的前缀。

我还考虑过创建一个带有数字及其组的类(100个组,每个组有1万个数字),以使洗牌更容易,但我认为这是更好,更简单的方法。

c# linq algorithm combinatorics

7
推荐指数
2
解决办法
318
查看次数

如何增加 .NET Core 中的传出 HTTP 请求配额?

我正在尝试从机器发送大量 HTTP 请求。但似乎 .NET Core 或我不知道的 Windows 正在限制可以发出的并发 HTTP 请求的数量,或者给定时间段内 HTTP 请求的配额。

我怎样才能增加这个?我记得我们在 .NET Framework 中有一个配置,但我也找不到。

c# concurrency http .net-core

7
推荐指数
2
解决办法
3146
查看次数

防止控制台应用程序(.NET Core)打印“代码为0退出”。在VS2019中

当我在Visual Studio社区2019(版本16.3.1)中使用Ctrl + F5(无需调试就开始)启动控制台应用程序(.NET Core)时,以下消息将附加在控制台窗口的末尾:

C:\ HelloWorld \ bin \ Debug \ netcoreapp3.0 \ HelloWorld.exe(进程1672)退出,代码为0。

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

控制台输出

有什么方法可以防止Visual Studio 2019打印此消息?我尝试通过更改以下选项来防止该解决方案出现在“输出”窗口中,该选项包括:“工具”>“选项”>“调试”>“输出”窗口>“进程退出消息” =“关闭”,但是在控制台窗口中无效。

Visual Studio选项

注意:此消息不会在Visual Studio 2017中显示。它只会在Visual Studio 2019中显示,并且仅在.NET Core应用程序中显示。

c# .net-core visual-studio-2019

7
推荐指数
1
解决办法
263
查看次数

如何强制 IAsyncEnumerable 遵守 CancellationToken

编辑:这个问题的要求已经改变。请参阅下面的更新部分。

我有一个异步迭代器方法,它产生一个IAsyncEnumerable<int>(数字流),每 200 毫秒一个数字。此方法的调用者使用流,但希望在 1000 毫秒后停止枚举。因此使用了 a CancellationTokenSource,并且将令牌作为参数传递给WithCancellation扩展方法。但令牌不受尊重。枚举一直持续到所有数字都被消耗完:

static async IAsyncEnumerable<int> GetSequence()
{
    for (int i = 1; i <= 10; i++)
    {
        await Task.Delay(200);
        yield return i;
    }
}

var cts = new CancellationTokenSource(1000);
await foreach (var i in GetSequence().WithCancellation(cts.Token))
{
    Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff} > {i}");
}
Run Code Online (Sandbox Code Playgroud)

输出:

12:55:17.506 > 1
12:55:17.739 > 2
12:55:17.941 > 3
12:55:18.155 > 4
12:55:18.367 > 5
12:55:18.520
: > 572 18 >
18 :55:18.973 > 8 …

c# cancellation c#-8.0 iasyncenumerable

7
推荐指数
1
解决办法
3587
查看次数

在 IMemoryCache 上调用扩展方法 GetOrCreateAsync 时是否可以避免缓存?

我正在使用 来IMemoryCache缓存从身份服务器检索到的令牌。

过去我使用过库GetOrCreateAsync中提供的扩展方法Microsoft.Extensions.Caching.Abstractions。这非常有帮助,因为我可以同时定义函数和到期日期。

但是,使用令牌时,在请求完成之前我不会知道x 秒后的过期值。我想通过根本不缓存令牌来解释不存在的值的用例。

我尝试过以下方法

var token = await this.memoryCache.GetOrCreateAsync<string>("SomeKey", async cacheEntry =>
{
    var jwt = await GetTokenFromServer();
    var tokenHasValidExpireValue = int.TryParse(jwt.ExpiresIn, out int tokenExpirationSeconds);
    
    if (tokenHasValidExpireValue)
    {
        cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(tokenExpirationSeconds);
    }
    else // Do not cache value.  Just return it.
    {
        cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(0); //Exception thrown.  Value needs to be positive.
    }

    return jwt.token;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,当我尝试设置 no time 过期时,会引发异常TimeSpan.FromSeconds(0)

除了分别调用GetSet方法之外,还有其他方法可以解决这个问题吗?如果可能的话我想使用该GetOrCreateAsync方法。

.net c# asynchronous memorycache .net-core

7
推荐指数
1
解决办法
1929
查看次数

重现“非并发集合必须具有独占访问权限”异常

我在生产应用程序中描述了https://dotnetfiddle.net/GknA5Q中的以下代码。用作缓存dictionary来保存对象的属性。使用此功能的REST API有数百种对象类型,因此当 API 找到更多对象类型时,缓存会变得更大。正如您在代码中看到的那样,对象的属性是通过反射检索的。当 API 启动并且数百个请求到达 API 时,就会填充这些内容。每个请求都会有一个对象类型,其属性会被缓存。dictionarydictionary

尽管 REST API 可以工作,但当 API 在 IIS 中启动时,代码现在会生成以下错误。生成错误的行号是TryGetValue被调用的23。

更改非并发集合的操作必须具有独占访问权限。对此集合执行并发更新并破坏了其状态。集合的状态不再正确。

我试图在测试应用程序中重现相同的错误,因此可以应用一些解决方案。我不想删除这dictionary会增加处理到达 API 的每个请求中的每个模型的时间。如果该dictionary缓存可用,则可以从缓存中检索属性,而不是通过反射进行解析。

我怎样才能重现上述错误?

c# collections dictionary thread-safety

7
推荐指数
1
解决办法
9133
查看次数

某处是否有 Ix.NET (System.Interactive) 的示例?

我有一个异步方法,说:

public async Task<T> GetAsync()
{

}
Run Code Online (Sandbox Code Playgroud)

并将从以下位置调用:

public async Task<IEnumerable<T>> GetAllAsync()
{
    foreach (var item in something)
    {
        var result = await GetAsync();
        yield return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的语法无效,但基本上我是在异步生成器之后。我知道它可以通过 Observables 处理。我对 Rx.NET 进行了实验,并且在一定程度上奏效了。但我试图避免它给代码库带来的复杂性,更重要的是,上述需求本质上仍然不是一个反应式系统(我们的仍然是基于拉取的)。例如,我只会在一段时间内收听传入的异步流,并且我必须从消费者端停止生产者(而不仅仅是取消订阅消费者)。

我可以像这样反转方法签名:

public IEnumerable<Task<T>> GetAllAsync()
Run Code Online (Sandbox Code Playgroud)

但这使得在不阻塞的情况下进行 LINQ 操作有点棘手。我希望它是非阻塞的,并且不将整个内容加载到内存中。这个库:AsyncEnumerable正是我正在寻找的,但如何用Ix.NET做到这一点?它们的用途与我相信的相同。

换句话说,我如何利用 Ix.NETIAsyncEnumerable在处理await? 喜欢,

public async IAsyncEnumerable GetAllAsync()
{
    foreach (var item in something)
    {
        var result = await GetAsync();
        return // what?
    }
}
Run Code Online (Sandbox Code Playgroud)

c# linq lazy-evaluation system.interactive rx.net

6
推荐指数
1
解决办法
2099
查看次数

Task.Run 中的异步 lambda 与常规 lambda

假设我有一个方法可以运行连续的 while 循环并进行一些异步调用

async Task MethodA(){
    while(true){ perform async/await operations }
}
Run Code Online (Sandbox Code Playgroud)

之间有什么区别:

Task.Run( () => MethodA(); }
Task.Run( async () => await MethodA(); }
Run Code Online (Sandbox Code Playgroud)

如果有区别,什么时候一个比另一个更有用?Task.Run 是否以不同的方式对待其每个重载?

c# task-parallel-library async-await

6
推荐指数
1
解决办法
2869
查看次数