Tag: 任务并行库

任务线程中抛出的exception,未被UnobservedTaskException捕获

我无法理解TPL中如何处理exception。 以下代码应说明我的问题。 using System; using System.Collections.Generic; using System.Net; using System.Threading; using System.Threading.Tasks; namespace WebDLApp { class Program { static void Main(string[] args) { TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; // Not catching exception List sites = new List{ “http://microsoft.com”, “http://yahoo.com”, “http://facebook.com”, “http://amazon.com”, “http://foooo”, “http://aol.com”, “http://ask.com”, “http://wikipedia.org” }; List<Task> tasks = new List<Task>(); foreach (string site in sites) { […]

TaskFactory.Tasks中BlockingCollection.GetConsumingEnumerable()集合的Parallel.ForEach和foreach循环

我已经尝试了这两个循环,并注意到即使Task的Action委托中的常规foreach循环应该并行执行,它也不会并行处理元素。 但是,如果我用Parallel.ForEach替换它,我会看到数据正在跨多个线程并行处理。 代码1: Task loadingTask1 = Factory.StartNew(() => { foreach (MyOneClass dg in Queue.GetConsumingEnumerable()) { MyOtherClass vl = new MyOtherClass(); vl.Id = dg.Id; vl.PerformTimeConsumingAction(); OutputQueue.Add(vl); } }); 代码2: Task loadingTask2 = Factory.StartNew(() => { Parallel.ForEach(Queue.GetConsumingEnumerable(), (dg) => { MyOtherClass vl = new MyOtherClass(); vl.Id = dg.Id; vl.PerformTimeConsumingAction(); OutputQueue.Add(vl); }); }); 在每次迭代时使用Console.Write语句运行的代码1似乎等待上一个循环完成,直到它抓住下一个循环,但代码2确实并行处理多个元素。 我是否正确理解Task.Action中的常规foreach? 我认为.NET将启动尽可能多的任务线程作为加载保证,并且每个迭代的foreach将被并行处理。 我也尝试将PLINQ结果传递给上述两个代码和观察者相同的行为:常规foreach似乎等待上一次迭代完成以启动下一个代码,即使我使用过.AsParallel()和.WithExecutionMode(ParallelExecutionMode.ForceParallelism)指令。 任何见解都将受到高度赞赏。 […]

如何更改异步方法调用以防止强制异步调用堆栈

如果我需要调用一个方法,在内部调用一些异步方法,作为一个fire and forget操作,我怎么能阻止这个调用强制“async”需要用完调用栈来说… MVC控制器? 例如:我的MVC控制器(非异步)调用业务层方法,该方法又调用Windows Azure Service Bus QueueClient.SendAsync(BrokeredMessage),将消息放入队列中,但不需要等待它完成。 通常,在调用此控制器操作时,编译器将抛出一个错误,指出此时无法启动异步操作。 我知道不是等待或只是调用SendAsync()方法,我可以使用ContinueWith()跟进它,以便在异步操作的回调上执行代码,但我被告知这不是一个正确的解决方案。 (请参阅对控制器中调用异步方法的响应) 有人会关心如何解决这种情况的最佳方法吗? 并告诉我为什么ContinueWith()方法不正确?

调度任务以供将来执行

我查看了Task和Timer类API,但无法找到有关如何安排Task以供将来执行的信息。 使用Timer类,我可以调度线程以供将来执行,但我需要安排Task 。 Task有.Delay(…)方法,但不确定延迟与调度类似。 编辑(澄清):我想在x分钟后启动任务。

为什么即使我尝试从工作器更改UI,同步上下文也为null,为什么工作人员在UI线程上等待,即使我不这样做?

我点击一个表单上的按钮,我称之为FooAsync并在完成时阻止UI线程。 以下是代码和我的问题。 using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace SynContextIfIDontTouchUIInWorkerThread { public partial class Form1 : Form { public Form1() { InitializeComponent(); } #pragma warning disable 1998 private async void button1_Click(object sender, EventArgs e) { // Nicely prints out the WindowsForms.SynchronizationContext // because we *are* indeed on the UI thread this.Text […]

Parallel.For使用step!= 1

有没有办法实现这个for循环的Parallel.For版本? for (int i = 0; i < 100; i += 2) { DoStuff(i); } 我没有看到接受步骤参数的重载,但我想不出任何理由这在逻辑上是不可能的。 对此和此问题的接受答案建议在使用Enumerable.Range生成的一系列int上使用Parallel.ForEach ,但在我的情况下,我使用线程本地数据, 因此Parallel.ForEach不是一个选项 。 另一种选择是检查我的循环体中是否i % 2 == 0并return ,但这仍然执行线程本地数据初始化器Func和终结器Func 。 以下是演示此选项的代码段: Parallel.For(0, limit, () => new Bar(), //thread local data initialize (i, state, local) => //loop body { if (i % 2 != 0) return local; local.foo += […]

我可以为此方案设计任何无锁解决方案

我有一个简单的Employee类如下 public class Employee { public int ID { get; set; } public string LastName { get; set; } public string FirstName { get; set; } } 然后我有一个ProcessEmployees类,它在名为ProcessThisEmployee的方法中对这些员工进行并发处理。 在这种方法中,我必须调用第三方库方法。 到目前为止一切都很简单。 问题是用户在进行操作时选择取消此操作的某个时候,我需要对尚未完成处理的任何ThirdPartyLibrary类实例进行一些清理。 注意我对ThirdPartyLibrary类没有任何控制,并且它没有任何取消现有任务的机制。 它提供了一个Clean方法,我可以在任何调用SomeAPI尚未完成的实例上调用它。 因此,我正在维护所有实例的本地列表。 当用户选择取消操作时,我调用我的类的CleaupIfUserCancelOperation方法,即清理我本地列表中第三方库实例的方法。 以下是我的代码。 class ProcessEmployees { private List _Employees; List libraries = new List(); private object sync = new object(); public ProcessEmployees() […]

使用异步套接字的多个套接字连接

我有以下代码,使TCP套接字连接到多个端点,如下所示: private async void button1_Click(object sender, EventArgs e) { var listofIps = new List { “192.168.168.193”, “192.168.168.221” }; foreach (var ip in listofIps) { IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 4001); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sockets.Add(client); await client.ConnectTaskAsync(remoteEP); await ReadAsync(client); } } async Task ReadAsync(Socket s) { var args = new SocketAsyncEventArgs(); args.SetBuffer(new […]

为什么有些本机线程在我的代码中没有原点的堆栈跟踪?

我使用任务并行库大量使用C#.NET 4.5应用程序,经过几天的操作后最终会因为线程而缺乏资源。 当我从AdPlus中获取HANG转储并通过Visual Studio查看线程时,我看到43个线程在我的代码中没有明显的起源: ntdll.dll!_NtWaitForSingleObject@12() + 0x15 bytes ntdll.dll!_NtWaitForSingleObject@12() + 0x15 bytes kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes 为什么这些线程在堆栈跟踪中没有显示托管源?

任务 .Result始终为null

我正在研究一些代码来通过Task.Factory.FromAsync(在WP7应用程序中)执行HttpRequest。 任务的Result属性始终为null,但我知道请求本身是正确的,因为如果我将它粘贴到我的浏览器或Fiddler中,它就可以工作。 这是我的代码: string _url = string.Format(“http://requestapi.net/{0}/{1}/{2}”, “objects”,”partitionKey”,”pkey1″); var request = (HttpWebRequest)WebRequest.Create(_url); request.Method = “GET”; Task task1 = Task.Factory.FromAsync( (callback, o) => ((HttpWebRequest)o).BeginGetResponse(callback, o) , result => ((HttpWebRequest)result.AsyncState).EndGetResponse(result) , request); task1.Start(); WebResponse webResponse = task1.Result; string responseString; using (var response = (HttpWebResponse)webResponse) { using (Stream streamResponse = response.GetResponseStream()) { StreamReader reader = new StreamReader(streamResponse); responseString […]