我有这个构造main(),它创造了
var tasks = new List<Task>();
var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
//DoBar not completed
t.Wait();
//Foo.Fim() done, Foo.DoBar should be but isn't
Run Code Online (Sandbox Code Playgroud)
但是,当我.Wait为t时,它不会等待呼叫DoBar()完成.我怎么让它实际等待?
我有一个使用冷(未启动)任务的缓存类,以避免多次运行昂贵的东西.
public class AsyncConcurrentDictionary<TKey, TValue> : System.Collections.Concurrent.ConcurrentDictionary<TKey, Task<TValue>>
{
internal Task<TValue> GetOrAddAsync(TKey key, Task<TValue> newTask)
{
var cachedTask = base.GetOrAdd(key, newTask);
if (cachedTask == newTask && cachedTask.Status == TaskStatus.Created) // We won! our task is now the cached task, so run it
cachedTask.Start();
return cachedTask;
}
}
Run Code Online (Sandbox Code Playgroud)
这很有效,直到您的任务实际使用C#5 await,ala实现
cache.GetOrAddAsync("key", new Task(async () => {
var r = await AsyncOperation();
return r.FastSynchronousTransform();
}));)`
Run Code Online (Sandbox Code Playgroud)
现在它看起来像TaskExtensions.Unwrap()我需要Task<Task<T>>变成一个Task<T>,但似乎它返回的包装实际上不支持Start()- 它抛出一个异常.
TaskCompletionSource (我去寻找稍微特殊的任务需求)似乎没有任何设施用于此类事情.
是否有替代方案TaskExtensions.Unwrap()支持"冷任务"?
我想同时启动一个Task对象集合,等待所有对象完成.以下代码显示了我想要的行为.
public class Program
{
class TaskTest
{
private Task createPauseTask(int ms)
{
// works well
return Task.Run(async () =>
// subsitution: return new Task(async () =>
{
Console.WriteLine($"Start {ms} ms pause");
await Task.Delay(ms);
Console.WriteLine($"{ms} ms are elapsed");
});
}
public async Task Start()
{
var taskList= new List<Task>(new[]
{
createPauseTask(1000),
createPauseTask(2000)
});
// taskList.ForEach(x => x.Start());
await Task.WhenAll(taskList);
Console.WriteLine("------------");
}
}
public static void Main()
{
var t = new TaskTest();
Task.Run(() => t.Start());
Console.ReadKey();
}
} …Run Code Online (Sandbox Code Playgroud) 我使用 ASP.NET Core Identity,通过 Jmeter 应用程序,我向我的 Web 应用程序发送多个请求以创建用户,它使用同一电子邮件创建了多个用户,尽管我的RequireUniqueEmail是true
services.AddIdentity<User, Role>(identityOptions =>
{
identityOptions.User.RequireUniqueEmail = true;
});
Run Code Online (Sandbox Code Playgroud)
当我一一发送请求时,一切正常,并在这段代码中给我重复的电子邮件错误
var result = await _userManager.CreateAsync(userToCreate, userPassword);
Run Code Online (Sandbox Code Playgroud)
但是当我使用 Jmeter 发送多个请求时,上面的代码无法处理重复的电子邮件,并且在 Jmeter 请求完成后,我打开 SQL Server,我看到至少创建了 10 条具有相同电子邮件的记录。我搜索了这个问题并得到了这个解决方案Using lock
private static readonly object lockObj = new object();
lock(lockObj)
{
var result = await _userManager.CreateAsync(userToCreate, userPassword);
}
Run Code Online (Sandbox Code Playgroud)
但它给了我错误并说“你不能在锁定语句中使用await”,第二个问题是ASP.NET Core Identity没有用于创建的Sync方法。如何在 ASP.NET Core Identity 中创建 create 的同步方法?
c# multithreading thread-synchronization async-await asp.net-core