我有WPF应用程序,在按钮单击处理程序中我想要启动多个任务(其中每个任务可以执行长时间运行).
我想向用户报告所有任务是否成功,或者是否成功,单个任务的错误是什么.
虽然区分至少一个例外或者所有例外,但我看不出一个好方法.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
namespace WPFTaskApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Task t1 = new Task(DoSomething);
Task t2 = new Task(DoSomethingElse);
t1.Start();
t2.Start();
// So now both tasks are running.
// I want to display one of two messages to the user:
// If both tasks completed ok, as …Run Code Online (Sandbox Code Playgroud) 有没有办法异步中止用#创建的C#TPL任务Task.Factory.Create(() => {stuff});?我已经看到有一种方法可以使用a,CancellationToken但我喜欢避免检查IsCancellationRequested.
我正在用几个位图构建一个Bitmap.我所做的是调用多个返回Task的方法.
我遇到的问题是死锁,因为我试图通过.Result从.ContinueWith()中的异步方法中检索值,这不起作用,因为它将异步方法转换为同步方法,这导致我陷入僵局.
我的问题是如何调用.ContinueWith中的异步方法,以及实现这种方法的正确方法是什么?
我需要删除.Result并正确调用异步方法任务.什么是正确的方法?
这是我的代码.
public async static Task<Bitmap> RollUpDrawingsImage(IElevation elevation)
{
int height = 0, width = 800;
Bitmap completeDrawings = null;
using (Bitmap elevationDoor = await ShopDrawing.Merger.MergeElevationAndDoor(elevation, RotateFlipType.Rotate90FlipNone))
{
using (Bitmap partsList = await MaterialsList.Manager.GetMaterialList(elevation).ContinueWith(async (ml) => await ml.Result.GetDrawing()).Result)
{
using (Bitmap optimized = await Optimization.Manager.GetOptimizedParts(elevation).ContinueWith(async (op) => await op.Result.GetDrawing()).Result)
{
using (Bitmap cutSheet = await CutSheet.Manager.GetCutSheet(elevation).ContinueWith(async (cs) => await cs.Result.GetDrawing()).Result)
{
height = (elevationDoor.Height + optimized.Height + cutSheet.Height + partsList.Height);
completeDrawings = new Bitmap(width, height + 40); …Run Code Online (Sandbox Code Playgroud) 我遇到的问题似乎与任务创建有关.在使用循环填充任务数组并在单独的循环中启动它之后,我的结果虽然一致,但却是错误的.但是,如果我单独填充数组,在循环内启动每个任务,一切都很好.任何人都可以给我一些建议吗?
例如,这是有问题的:
int c = 1;
for (int i = 1; i <= 4; i++)
{
taskArray[i-1] = new Task(() => calculateRows(c, true));
c = c + 2;
}
foreach (Task t in taskArray) t.Start();
Run Code Online (Sandbox Code Playgroud)
但这很好用:
taskArray[0] = new Task(() => calculateRows(1, true));
taskArray[1] = new Task(() => calculateRows(3, true));
taskArray[2] = new Task(() => calculateRows(5, true));
taskArray[3] = new Task(() => calculateRows(7, true));
foreach (Task t in taskArray) t.Start();
Run Code Online (Sandbox Code Playgroud) 我有以下代码,它创建了多个任务来同时处理数据.我想知道完成工作的任务会发生什么变化?他们会自动处理吗?
var itemListByGroups = items.GroupBy(x => x.SomeValue);
List<Task> tasks = new List<Task>();
// Can create 20 to 30 tasks based on the result of the grouping
foreach (var itemList in itemListByGroups)
{
var task = Task.Factory.StartNew(() =>
{
// intense processing
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
Run Code Online (Sandbox Code Playgroud)
当有更多项目要处理时,上面的代码会每几秒钟调用一次,我关心的是任务数量会继续增长吗?
我的应用程序有一个包含Lazy<BitmapImage>字段的View Model .使用对服务器的服务调用填充该字段.在图像很大的情况下,服务器返回图像(实际上是a byte[])需要几秒钟,因此UI被阻止.为了防止这种情况,我将服务调用放在a中Task,以便后台线程获取图像然后调用OnPropertyChanged以让UI知道返回的图像:
Console.WriteLine("Outside Task ThreadID: {0}",
Thread.CurrentThread.ManagedThreadId);
Task.Factory.StartNew(() =>
{
Console.WriteLine("Inside Task ThreadID: {0}", Thread.CurrentThread.ManagedThreadId);
return Utilities.ConvertByteToImage(
SessionService.GetUserInformation(UserInfo.From).ProfilePicture);
}).ContinueWith(resultToken =>
{
m_lazyProfilePicture = new Lazy<BitmapImage>(() =>
{
return (resultToken.Result == null) ? Utilities.DefaultProfilePicture.Value : resultToken.Result;
});
OnPropertyChanged("ProfilePicture");
});
Run Code Online (Sandbox Code Playgroud)
我注意到,即使将服务调用放入a Task,UI也会被阻止.因此,添加这些Console.WriteLine行以查看线程ID.令人惊讶的是,它们都报告了相同的线程ID(这似乎只发生在这种情况下.我在项目中尝试了其他任务,并且它们都报告了不同的ID).知道这里发生了什么吗?这跟它有什么关系BitmapImage吗?由于某种原因,调度程序决定将任务放在同一个线程中,但我不明白为什么.欢迎任何建议!
我是C#4.0中并行编程类的新手; 正在尝试一个简单的for循环,我应该通过常规的for循环以顺序的方式从0到99打印,但是使用Parallel.For,我会在随机混乱的顺序中获得不连续的输出.
代码:
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Parallel.For(0, 100, i =>
{
//object sync = new object();
//lock (sync)
{
Console.WriteLine("Writing" + i);
}
});
Console.Read();
}
}
}
Run Code Online (Sandbox Code Playgroud)
控制台上的一个输出:
Writing0
Writing1
Writing2
Writing3
Writing4
Writing5
Writing6
Writing7
Writing8
Writing9
Writing10
Writing11
Writing12
Writing13
Writing14
Writing15
Writing16
Writing17
Writing18
Writing19
Writing20
Writing21
Writing22
Writing23
Writing24
Writing25
Writing26
Writing27
Writing28
Writing29
Writing30
Writing31
Writing32
Writing33
Writing34
Writing35
Writing36
Writing37
Writing38
Writing39
Writing40 …Run Code Online (Sandbox Code Playgroud) 我正在努力解开C#异步编程,下面的模式显然是错误的,但是我不明白.我打算做的就是解雇n个任务,然后等待它们全部完成.当我明白我感到困惑时,我开始将事情提炼下来,并最终创造了这个:
private async Task<bool> doLoop()
{
int loopCnt = 3;
int[] sleeperReturns = new int[loopCnt + 1];
for (int i = 0; i < loopCnt; i++)
{
System.Diagnostics.Debug.WriteLine("doLoop: i={0} calling Sleeper", i);
Task.Run(async () => { sleeperReturns[i] = await sleep(i); });
System.Diagnostics.Debug.WriteLine("doLoop: i={0} called Sleeper", i);
}
return true;
}
private async Task<int> sleep(int i)
{
System.Diagnostics.Debug.WriteLine("Sleep: begins i={0}", i);
await Task.Delay(5000 + i * 1000);
System.Diagnostics.Debug.WriteLine("Sleep: ends i={0}", i);
return i;
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
doLoop: i=0 calling Sleeper
doLoop: i=0 …Run Code Online (Sandbox Code Playgroud) 我是线程和并行库的新手。我试图了解MaxDegreeOfParallelism以及应将其设置为什么值。
做一些阅读,对我来说可能有点误导。
如果我想在4个线程上运行,我想我可以做
var parOptions=new ParallelOptions();
parOptions.MaxDegreeOfParallelism=4;
Run Code Online (Sandbox Code Playgroud)
但是,在我的情况下,多读一些内容似乎并不意味着可以在4个线程上运行,而是更多地涉及Cores及其使用量。
为简单起见,设置应运行的线程数的正确方法是什么?或者,也许您可以在它可以使用的多个线程上进行设置,但是可以在其使用的核心数量上进行更多设置
我打算在config.eg“ ThreadCount”中设置一个用户可以指定的值。这是其他开发人员将运行的内部应用程序,用于导入内容。
任何澄清吗?谢谢
我有一个库调用,我需要在超时中包装,因为它挂起了某些输入.
看来这Task.Wait(timeout)是最简单的方法.但它没有做我期望的事情.这是一个测试用例(对于类似linqpad的测试环境):
class A { public int X; }
public static void Main() {
var o = new A { X = 0 };
new Task(() => { o.X = 1; }).RunSynchronously();
o.X.Dump(); // Says "1" immediately
new Task(() => { o.X = 2; }).Wait(2000);
o.X.Dump(); // Says "1" after 2 seconds
}
Run Code Online (Sandbox Code Playgroud)
为什么第二次呼叫超时,从不执行任务?我误解了API吗?
更新:@ ThomasLevesque的回答是正确的,我需要Run完成任务.但是,我现在发现Wait超时无效.我的实际案例涉及SmartXLS组件.我取代了这个
// hangs for some workbooks (as in, never returns and hoses the process, or falls to request …Run Code Online (Sandbox Code Playgroud)