Tag: 任务

如何正确取消在后台STA线程上运行的打印任务?

[请注意:这个问题在我的另一个问题中得到了有效解决: 如何使用canceltokensource取消后台打印 ] 我一直在使用以下方法(从SO)运行我的打印机并在后台线程上打印预览: public static Task StartSTATask(Action func) { var tcs = new TaskCompletionSource(); var thread = new Thread(() => { try { func(); tcs.SetResult(null); } catch (Exception e) { tcs.SetException(e); } }); thread.SetApartmentState(ApartmentState.STA); thread.Priority = ThreadPriority.AboveNormal; thread.Start(); return tcs.Task; } 它运行完美,没有错误。 我不知道如何适当地取消这个任务。 我应该完全中止线程还是传入CancellationTokenSource令牌? 如何更改上述代码以允许取消(或中止)? 我很迷茫。 感谢您对此的任何帮助。 (经过大量的谷歌搜索,这里的解决方案根本不像我希望的那样微不足道!) 经过深思熟虑后,我倾向于将CancellationToken传递给正在执行的func(),并强制终止该函数。 在这种情况下,这意味着要关闭PrintDialogue()。 还有另一种方式吗? 我使用上面的代码: public override […]

关于Task.StartNew(Action ,Object)方法

我在这个页面上学习TPL,一个代码块让我很困惑。 我正在阅读此页面: 任务并行(任务并行库) 在一节中,它说下面的代码是正确的解决方案,因为循环中的lambda不能获得每次迭代后变异的值,而是最终值。 所以你应该在CustomData对象中包装“i”。 代码如下: class CustomData { public long CreationTime; public int Name; public int ThreadNum; } public class Example { public static void Main() { // Create the task object by using an Action(Of Object) to pass in custom data // to the Task constructor. This is useful when you need to […]

在任务中重新抛出exception(TPL)会丢失堆栈跟踪

我的代码重新抛出exception。 当我稍后从task.Exception读取exception时,它的stacktrace指向我重新抛出exception的位置(行n而不是行m,正如我所料)。 为什么会这样? TPL中的错误或更可能是我忽略的东西。 当我解决方法时,我可以将exception包装为新exception中的内部exception。 internal class Program { private static void Main(string[] args) { Task.Factory.StartNew(TaskMethod).ContinueWith(t => Console.WriteLine(t.Exception.InnerException)); Console.Read(); } private static void TaskMethod() { try { line m: throw new Exception(“Todo”); } catch (Exception) { line n: throw; } } }

我是否需要担心阻止任务?

我需要担心在.NET中阻塞任务多少钱? 即.NET任务调度程序如何处理线程池中的线程阻塞和超额订阅? 例如,如果我在任务中有一些IO,我是否应该始终使用LongRunning提示创建它? 或者任务调度程序启发式更好地处理它? 在C ++中有一个Oversubscribe提示可以很好地工作,但我没有在.NET中找到任何等价物。

SSIS通过脚本任务写入对象变量

我有一些代码,我想最终得到2个列表。 开始和结束。 它们包含月份的开始日期和月份的结束日期。 这两个列表我想放入一个对象变量,所以我可以在ssis中的foreachloop容器中使用该对象,并使用startofmonth和endofmonthdates循环遍历每一行(变量:min和max) – 但我不知道如何 这是我的代码: String s = “2013-01-01”; String b = “2014-01-01”; using (SqlConnection connection = new SqlConnection(“Server=localhost;Initial Catalog=LegOgSpass;Integrated Security=SSPI;Application Name=SQLNCLI11.1”)) { connection.Open(); string query = “select mindate,maxdate from dbo.dates”; using (SqlCommand command = new SqlCommand(query, connection)) { using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { s = reader.GetDateTime(0).ToShortDateString(); b = […]

将async / await与Result混合

让我先简单介绍一下这个问题: 我已经阅读了几个SO问题,说你不应该这样做(比如如何安全地混合同步和异步代码 ) 我已经读过Async / Await – 异步编程中的最佳实践再次说你不应该这样做 所以我知道这不是最佳做法,也不需要任何人告诉我这样做。 这更像是“为什么这个工作”的问题。 有了这个,这是我的问题: 我写了一个小的GUI应用程序,它有2个按钮和一个状态标签。 其中一个按钮将在100%的时间内重现同步和异步的死锁问题。 另一个按钮调用相同的异步方法,但它包含在一个任务中,这个工作。 我知道这不是一个好的编码实践,但我想理解它为什么没有相同的死锁问题。 这是代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async Task DelayAsync() { await Task.Delay(1000); return “Done”; } private void buttonDeadlock_Click(object sender, EventArgs e) { labelStatus.Text = “Status: Running”; // causes a deadlock because of […]

将参数传递给Task.Factory.StartNew

给出以下代码: string injectedString = “Read string out of HttpContext”; Task.Factory.StartNew(() => { MyClass myClass = new MyClass(); myClass.Method(injectedString); } 这是将字符串传递给任务/线程的最佳方法吗? 我对这种方法的担忧是: 垃圾收集器是否知道字符串何时脱离上下文并正确清理它? 是否有更好的方法将依赖项注入到主线程中断开对象链接的任务? 这是在Asp.Net网络服务中,如果它很重要并且是一个火灾和忘记类型的线程,我不是在等待任何类型的响应。 我的字符串实际上是从HttpContext读出来的,这是我以这种方式注入它的一个原因(Thread无法访问调用线程HtppContext )

通过等待任务或访问其Exception属性,未观察到任务的exception

这些是我的任务。 我应该如何修改它们以防止此错误。 我检查了其他类似的线程,但我正在使用等待并继续。 那怎么会发生这个错误呢? 通过等待任务或访问其Exception属性,未观察到任务的exception。 结果,终结器线程重新抛出了未观察到的exception。 var CrawlPage = Task.Factory.StartNew(() => { return crawlPage(srNewCrawledUrl, srNewCrawledPageId, srMainSiteId); }); var GetLinks = CrawlPage.ContinueWith(resultTask => { if (CrawlPage.Result == null) { return null; } else { return ReturnLinks(CrawlPage.Result, srNewCrawledUrl, srNewCrawledPageId, srMainSiteId); } }); var InsertMainLinks = GetLinks.ContinueWith(resultTask => { if (GetLinks.Result == null) { } else { instertLinksDatabase(srMainSiteURL, […]

如何启动异步任务对象

我想同时启动一个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(new[] { createPauseTask(1000), createPauseTask(2000) }); // […]

应该何时将任务视为“长时间运行”?

在处理任务时,经验法则似乎是线程池 – 通常由例如调用Task.Run()或Parallel.Invoke() – 应该用于相对较短的操作。 在处理长时间运行的操作时,我们应该使用TaskCreationOptions.LongRunning标志,以便 – 据我所知 – 避免堵塞线程池队列,即将工作推送到新创建的线程。 但究竟什么是长期运行 ? 从时间上看,多长时间? 在决定是否使用LongRunning ,是否还要考虑除预期任务持续时间之外的其他因素,例如预期的CPU架构(频率,核心数……)或将尝试的任务数量从程序员的角度立刻运行? 例如,假设我有500个任务要在专用应用程序中处理,每个任务需要10-20秒才能完成。 我应该只使用Task.Run启动所有500个任务(例如在循环中),然后等待它们全部,可能是LongRunning ,同时保留默认的最大并发级别? 然后,如果我在这种情况下设置LongRunning ,那么与省略LongRunning相比,这不会创建500个新线程并且实际上会导致大量开销和更高的内存使用(由于额外的线程被分配)? 这假设在等待这500个任务时不会安排执行新任务。 我猜想设置LongRunning的决定取决于在给定时间间隔内对线程池发出的请求数,而LongRunning只应该用于预期比大多数线程池花费更长时间的任务 -放置任务 – 根据定义,最多只占所有任务的一小部分。 换句话说,这似乎是一个排队和线程池利用率优化问题,应该通过测试逐个解决,如果有的话。 我对么?