我正在使用完全异步的API客户端,也就是说,每个操作都返回Task或者Task<T>,例如:
static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}
Run Code Online (Sandbox Code Playgroud)
使用C#5 async/await运算符,启动多个任务并等待它们全部完成的正确/最有效方法是什么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
Run Code Online (Sandbox Code Playgroud)
要么:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
Run Code Online (Sandbox Code Playgroud)
由于API客户端在内部使用HttpClient,我希望这会立即发出5个HTTP请求,并在每个请求完成时写入控制台.
我有3个任务:
private async Task<Cat> FeedCat() {}
private async Task<House> SellHouse() {}
private async Task<Tesla> BuyCar() {}
Run Code Online (Sandbox Code Playgroud)
他们都需要在我的代码可以继续之前运行,我也需要每个代码的结果.结果没有任何共同之处
如何调用并等待3个任务完成然后获得结果?
在这段代码中:
private async void button1_Click(object sender, EventArgs e) {
try {
await Task.WhenAll(DoLongThingAsyncEx1(), DoLongThingAsyncEx2());
}
catch (Exception ex) {
// Expect AggregateException, but got InvalidTimeZoneException
}
}
Task DoLongThingAsyncEx1() {
return Task.Run(() => { throw new InvalidTimeZoneException(); });
}
Task DoLongThingAsyncEx2() {
return Task.Run(() => { throw new InvalidOperation();});
}
Run Code Online (Sandbox Code Playgroud)
我期望WhenAll创建并抛出一个AggregateException,因为至少有一个等待抛出异常的任务.相反,我正在收回其中一个任务抛出的单个异常.
难道WhenAll不总是创造AggregateException?
我有这个代码:
List<ComponentesClasificaciones> misClasificaciones = new List<ComponentesClasificaciones>();
Task tskClasificaciones = Task.Run(() =>
{
misClasificaciones = VariablesGlobales.Repositorio.buscarComponentesClasificacionesTodosAsync().Result;
});
Task.WhenAll(tskClasificaciones);
List<ComponentesClasificaciones> misVClasificacionesParaEstructuras = new List<ComponentesClasificaciones>(misClasificaciones);
Run Code Online (Sandbox Code Playgroud)
如果我使用Task.WhenAll,misClasificaciones没有任何元素,但是当我使用awit时,我得到了我向数据库请求的所有元素.
何时使用WhenAll以及何时使用WaitAll?
我正在处理一个任务并行问题,我有许多任务可能会或可能不会抛出异常.
我想处理所有正确完成的任务并记录其余的任务.在Task.WaitAll不允许我收集其余结果的情况下支持Task异常.
static readonly Task<string> NormalTask1 = Task.FromResult("Task result 1");
static readonly Task<string> NormalTask2 = Task.FromResult("Task result 2");
static readonly Task<string> ExceptionTk = Task.FromException<string>(new Exception("Bad Task"));
var results = await Task.WaitAll(new []{ NormalTask1,NormalTask2,ExceptionTk});
Run Code Online (Sandbox Code Playgroud)
在Task.Waitall 与抛出的异常ExcceptionTk忽略其它结果.我怎样才能得到忽略异常的结果并同时记录异常?
我可以将任务包装到try{...}catch(){...}内部异常的另一个任务中,但我无法访问它们,我希望我不必添加这个开销.
Task当它完成时我正在重新运行.下面是我在Application_Start我的应用程序中调用的函数.
private void Run()
{
Task t = new Task(() => new XyzServices().ProcessXyz());
t.Start();
t.ContinueWith((x) =>
{
Thread.Sleep(ConfigReader.CronReRunTimeInSeconds);
Run();
});
}
Run Code Online (Sandbox Code Playgroud)
我想运行多个任务,编号将从web.config app setttings中读取.
我正在尝试这样的事情,
private void Run()
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < ConfigReader.ThreadCount - 1; i++)
{
tasks.Add(Task.Run(() => new XyzServices().ProcessXyz()));
}
Task.WhenAll(tasks);
Run();
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?
我在很多地方都读过 ConfigureAwait(包括 SO 问题),以下是我的结论:
.ConfigureAwait(true). 否则,由于另一个线程访问 UI 元素,将发生 InvalidOperationException。我的问题是:
我需要让UI线程等待,直到任务数组完成执行.下面的代码的问题是 - 任务inturn调用UI线程写入文本框.如何解决这个问题?
public partial class FormConsole : Form
{
public FormConsole()
{
InitializeComponent();
}
void txtSayHello_Click(object sender, EventArgs e)
{
Class1 objclss = new Class1();
objclss.formConsole = this;
Task[] taa = new Task[4];
taa[0] = new Task(() => objclss.DoSomeThigs("Hello world"));
taa[1] = new Task(() => objclss.DoSomeThigs("Hello world1"));
taa[2] = new Task(() => objclss.DoSomeThigs("Hello world2"));
taa[3] = new Task(() => objclss.DoSomeThigs("Hello world3"));
foreach(Task task in taa)
{
task.Start();
}
Task.WhenAll(taa);
this.txtConsole.AppendText("All threads complete");
}
delegate void doStuffDelegate(string value);
public void …Run Code Online (Sandbox Code Playgroud) 我的要求很奇怪.
我有SomeMethod()哪些电话GetDataFor().
public void SomeMethod()
{
for(int i = 0; i<100; i++) {
var data = GetDataFor(i);
}
}
public data GetDataFor(int i) {
//call a remote API
//to generate data for i
//store to database
return data;
}
Run Code Online (Sandbox Code Playgroud)
对于每一个i,最终结果总是不同的.有没有需要等待的GetDataFor(i)调用之前完成GetDataFor(i+1).
换句话说,我需要:
GetDataFor()每个i+1 立即成功后调用i(并行调用它们看起来不可能的)GetDataFor()都完成运行SomeMethod()按照YK1的回答,我试图像这样修改它:
public async Task<void> SomeMethod()
{
for(int i …Run Code Online (Sandbox Code Playgroud) 我知道Task.WaitAll(Task1,Task2)等待所有提供的Task对象完成执行.
什么是Task.WhenAll用于什么?
创建将在所有提供的任务完成后完成的任务.
什么是真实世界场景,曾经可以应用Task.WhenAll()
c# ×9
.net ×6
task ×5
async-await ×4
asynchronous ×4
exception ×2
.net-4.5 ×1
begininvoke ×1
c#-5.0 ×1
performance ×1
tap ×1
winforms ×1