PHP脚本在每次迭代时花费的时间越来越长,以保存数据(PHP script taking longer and longer on each iteration to save data)
我编写了一个自动化脚本来解析本地的XML文件,从XML中提取一些URL,然后下载URL指向的文件并存储数据(所有jpg)。 每次后续迭代都会逐渐变长。 最终,脚本挂起,没有任何反应。 哦,内存使用似乎保持不变。 XML解析工作正常,所以请不要过多地讨论它。 如果我在脚本完全停止的游戏中启动脚本,则会在一秒钟内将文件保存到磁盘,因为这是脚本执行的第一次保存。 是什么造成的? 这是代码:
<?php $xml = simplexml_load_file('./playfin.xml', null, LIBXML_NOCDATA); echo("Getting urls from the XML...\n"); $data = array(); foreach($xml->game as $game) { $smlBox = $game->small_boxshot_image->url; $lrgBox = $game->large_boxshot_image->url; foreach($game->screenshots->screenshot_image as $image) { $scrShots[] = array( 'smlScr' => (string)$image->small_screenshot_image->url, 'lrgScr' => (string)$image->large_screenshot_image->url ); } $data[] = array( 'id' => (int)$game->game_id, 'smlBox' => (string)$smlBox, 'lrgBox' => (string)$lrgBox, 'scrShots' => $scrShots ); } echo("Done pulling urls from XML...\n"); echo("Storing picture data to disk...\n"); $start = time(); $total = 0; $now = 0; for($i = 0; $i < count($data); $i++) { $total += $now; $now = time() - $start - $total; echo("Writing game id: ".$data[$i]['id']. ." to disk at time=".(string)$now." seconds.\n"); echo("Memory usage: ".(string)memory_get_usage(true)."\n\n"); $smlBoxStr = '%s_49_60.jpg'; $lrgBoxStr = '%s_160_189.jpg'; $smlScrStr = '%s_115_86_%d.jpg'; $lrgScrStr = '%s_300_300_%d.jpg'; writeData($data[$i]['smlBox'], sprintf($smlBoxStr, $data[$i]['id']), 'boxshot'); writeData($data[$i]['lrgBox'], sprintf($lrgBoxStr, $data[$i]['id']), 'boxshot'); for($j = 0; $j < count($data[$i]['scrShots']); $j++) { writeData( $data[$i]['scrShots'][$j]['smlScr'], sprintf($smlScrStr, $data[$i]['id'], $j), 'screenshot' ); writeData( $data[$i]['scrShots'][$j]['lrgScr'], sprintf($lrgScrStr, $data[$i]['id'], $j), 'screenshot' ); } } echo("Done storing!\n"); echo("Done!\n"); function writeData($url, $file, $type) { $headers = get_headers($url, 1); $awayPic = fopen($url, 'rb'); $localPic = fopen("./$type/$file", 'wb'); while($picData = fread($awayPic, (int)$headers['Content-Length'])) { fwrite($localPic, $picData); } fclose($awayPic); fclose($localPic); } ?>
这是生成的日志文件:
从XML获取网址...从XML中提取网址...将图片数据存储到磁盘...将游戏ID:671850写入磁盘时间= 0秒。 内存使用情况:77856768
在时间= 0秒时将游戏ID:730950写入磁盘。 内存使用情况:77856768
在时间= 1秒时将游戏ID:621650写入磁盘。 内存使用情况:77856768
在时间= 1秒时将游戏ID:687250写入磁盘。 内存使用情况:77856768
在时间= 7秒时将游戏ID:633950写入磁盘。 内存使用情况:77856768
在时间= 2秒时将游戏ID:633850写入磁盘。 内存使用情况:77856768
在时间= 2秒时将游戏ID:720950写入磁盘。 内存使用情况:77856768
在时间= 3秒时将游戏ID:572250写入磁盘。 内存使用情况:77856768
在时间= 3秒时将游戏ID:674950写入磁盘。 内存使用情况:77856768
在时间= 3秒时将游戏ID:731450写入磁盘。 内存使用情况:77856768
将游戏ID:656350写入磁盘时间= 4秒。 内存使用情况:77856768
在时间= 4秒时将游戏ID:653550写入磁盘。 内存使用情况:77856768
在时间= 4秒时将游戏ID:585550写入磁盘。 内存使用情况:77856768
在时间= 5秒时将游戏ID:736750写入磁盘。 内存使用情况:77856768
在时间= 5秒时将游戏ID:671350写入磁盘。 内存使用情况:77856768
在时间= 5秒时将游戏ID:696250写入磁盘。 内存使用情况:77856768
在时间= 6秒时将游戏ID:645550写入磁盘。 内存使用情况:77856768
在时间= 6秒时将游戏ID:625650写入磁盘。 内存使用情况:77856768
在时间= 6秒时将游戏ID:696850写入磁盘。 内存使用情况:77856768
在时间= 7秒时将游戏ID:709550写入磁盘。 内存使用情况:77856768
在时间= 7秒时将游戏ID:575750写入磁盘。 内存使用情况:77856768
将游戏ID:651950写入磁盘时间= 7秒。 内存使用情况:77856768
在时间= 8秒时将游戏ID:685350写入磁盘。 内存使用情况:77856768
在时间= 9秒时将游戏ID:724150写入磁盘。 内存使用情况:77856768
在时间= 8秒时将游戏ID:522250写入磁盘。 内存使用情况:77856768
在时间= 10秒时将游戏ID:610350写入磁盘。 内存使用情况:77856768
在时间= 9秒时将游戏ID:645050写入磁盘。 内存使用情况:77856768
在时间= 9秒时将游戏ID:716950写入磁盘。 内存使用情况:77856768
在时间= 10秒时将游戏ID:672750写入磁盘。 内存使用情况:77856768
在时间= 11秒时将游戏ID:568650写入磁盘。 内存使用情况:77856768
在时间= 11秒时将游戏ID:668650写入磁盘。 内存使用情况:77856768
在时间= 11秒时将游戏ID:417950写入磁盘。 内存使用情况:77856768
在时间= 13秒时将游戏ID:497950写入磁盘。 内存使用情况:77856768
在时间= 12秒时将游戏ID:567950写入磁盘。 内存使用情况:77856768
在时间= 13秒时将游戏ID:692350写入磁盘。 内存使用情况:77856768
在时间= 13秒时将游戏ID:450950写入磁盘。 内存使用情况:77856768
在时间= 14秒时将游戏ID:452750写入磁盘。 内存使用情况:77856768
在时间= 14秒时将游戏ID:666450写入磁盘。 内存使用情况:77856768
在时间= 15秒时将游戏ID:754550写入磁盘。 内存使用情况:77856768
在时间= 15秒时将游戏ID:659050写入磁盘。 内存使用情况:77856768
在时间= 15秒时将游戏ID:712350写入磁盘。 内存使用情况:77856768
在时间= 16秒时将游戏ID:719250写入磁盘。 内存使用情况:77856768
在时间= 15秒时将游戏ID:529250写入磁盘。 内存使用情况:77856768
在时间= 17秒时将游戏ID:685150写入磁盘。 内存使用情况:77856768
在时间= 17秒时将游戏ID:736450写入磁盘。 内存使用情况:77856768
在时间= 17秒时将游戏ID:252750写入磁盘。 内存使用情况:77856768
在时间= 17秒时将游戏ID:719150写入磁盘。 内存使用情况:77856768
在时间= 18秒时将游戏ID:461150写入磁盘。 内存使用情况:77856768
在时间= 18秒时将游戏ID:699450写入磁盘。 内存使用情况:77856768
在时间= 18秒时将游戏ID:523550写入磁盘。 内存使用情况:77856768
在时间= 20秒时将游戏ID:451050写入磁盘。 内存使用情况:77856768
在时间= 19秒时将游戏ID:768350写入磁盘。 内存使用情况:77856768
在时间= 20秒时将游戏ID:724650写入磁盘。 内存使用情况:77856768
在时间= 21秒时将游戏ID:676550写入磁盘。 内存使用情况:77856768
在时间= 21秒时将游戏ID:730850写入磁盘。 内存使用情况:77856768
在时间= 22秒时将游戏ID:558250写入磁盘。 内存使用情况:77856768
在时间= 22秒时将游戏ID:674750写入磁盘。 内存使用情况:77856768
在时间= 22秒时将游戏ID:695450写入磁盘。 内存使用情况:77856768
在时间= 22秒时将游戏ID:682950写入磁盘。 内存使用情况:77856768
在时间= 24秒时将游戏ID:706450写入磁盘。 内存使用情况:77856768
在时间= 24秒时将游戏ID:546450写入磁盘。 内存使用情况:77856768
在时间= 24秒时将游戏ID:575350写入磁盘。 内存使用情况:77856768
在时间= 25秒时将游戏ID:616550写入磁盘。 内存使用情况:77856768
在时间= 26秒时将游戏ID:648250写入磁盘。 内存使用情况:77856768
在时间= 25秒时将游戏ID:763750写入磁盘。 内存使用情况:77856768
在时间= 26秒时将游戏ID:613850写入磁盘。 内存使用情况:77856768
在时间= 25秒时将游戏ID:645450写入磁盘。 内存使用情况:77856768
在时间= 33秒时将游戏ID:695950写入磁盘。 内存使用情况:77856768
在时间= 27秒时将游戏ID:661050写入磁盘。 内存使用情况:77856768
在时间= 27秒时将游戏ID:461050写入磁盘。 内存使用情况:77856768
在时间= 29秒时将游戏ID:693150写入磁盘。 内存使用情况:77856768
谢谢!
I wrote an automation script to parse an XML file on local, pull some urls from the XML, and then download the files pointed to by the urls and store the data(all jpg's). Every subsequent iteration progressively takes longer and longer. Eventually, the script just hangs and nothing happens. Oh, the memory usage appears to remain constant. The XML parsing works fine, so please don't dwell on that too much. If I start the script at a game where the script stops altogether, is saves the files to disk in under a second, because it is the first save the script does. What is causing this? Here's the code:
<?php $xml = simplexml_load_file('./playfin.xml', null, LIBXML_NOCDATA); echo("Getting urls from the XML...\n"); $data = array(); foreach($xml->game as $game) { $smlBox = $game->small_boxshot_image->url; $lrgBox = $game->large_boxshot_image->url; foreach($game->screenshots->screenshot_image as $image) { $scrShots[] = array( 'smlScr' => (string)$image->small_screenshot_image->url, 'lrgScr' => (string)$image->large_screenshot_image->url ); } $data[] = array( 'id' => (int)$game->game_id, 'smlBox' => (string)$smlBox, 'lrgBox' => (string)$lrgBox, 'scrShots' => $scrShots ); } echo("Done pulling urls from XML...\n"); echo("Storing picture data to disk...\n"); $start = time(); $total = 0; $now = 0; for($i = 0; $i < count($data); $i++) { $total += $now; $now = time() - $start - $total; echo("Writing game id: ".$data[$i]['id']. ." to disk at time=".(string)$now." seconds.\n"); echo("Memory usage: ".(string)memory_get_usage(true)."\n\n"); $smlBoxStr = '%s_49_60.jpg'; $lrgBoxStr = '%s_160_189.jpg'; $smlScrStr = '%s_115_86_%d.jpg'; $lrgScrStr = '%s_300_300_%d.jpg'; writeData($data[$i]['smlBox'], sprintf($smlBoxStr, $data[$i]['id']), 'boxshot'); writeData($data[$i]['lrgBox'], sprintf($lrgBoxStr, $data[$i]['id']), 'boxshot'); for($j = 0; $j < count($data[$i]['scrShots']); $j++) { writeData( $data[$i]['scrShots'][$j]['smlScr'], sprintf($smlScrStr, $data[$i]['id'], $j), 'screenshot' ); writeData( $data[$i]['scrShots'][$j]['lrgScr'], sprintf($lrgScrStr, $data[$i]['id'], $j), 'screenshot' ); } } echo("Done storing!\n"); echo("Done!\n"); function writeData($url, $file, $type) { $headers = get_headers($url, 1); $awayPic = fopen($url, 'rb'); $localPic = fopen("./$type/$file", 'wb'); while($picData = fread($awayPic, (int)$headers['Content-Length'])) { fwrite($localPic, $picData); } fclose($awayPic); fclose($localPic); } ?>
Here's the log file that was produced:
Getting urls from the XML... Done pulling urls from XML... Storing picture data to disk... Writing game id: 671850 to disk at time=0 seconds. Memory usage: 77856768
Writing game id: 730950 to disk at time=0 seconds. Memory usage: 77856768
Writing game id: 621650 to disk at time=1 seconds. Memory usage: 77856768
Writing game id: 687250 to disk at time=1 seconds. Memory usage: 77856768
Writing game id: 633950 to disk at time=7 seconds. Memory usage: 77856768
Writing game id: 633850 to disk at time=2 seconds. Memory usage: 77856768
Writing game id: 720950 to disk at time=2 seconds. Memory usage: 77856768
Writing game id: 572250 to disk at time=3 seconds. Memory usage: 77856768
Writing game id: 674950 to disk at time=3 seconds. Memory usage: 77856768
Writing game id: 731450 to disk at time=3 seconds. Memory usage: 77856768
Writing game id: 656350 to disk at time=4 seconds. Memory usage: 77856768
Writing game id: 653550 to disk at time=4 seconds. Memory usage: 77856768
Writing game id: 585550 to disk at time=4 seconds. Memory usage: 77856768
Writing game id: 736750 to disk at time=5 seconds. Memory usage: 77856768
Writing game id: 671350 to disk at time=5 seconds. Memory usage: 77856768
Writing game id: 696250 to disk at time=5 seconds. Memory usage: 77856768
Writing game id: 645550 to disk at time=6 seconds. Memory usage: 77856768
Writing game id: 625650 to disk at time=6 seconds. Memory usage: 77856768
Writing game id: 696850 to disk at time=6 seconds. Memory usage: 77856768
Writing game id: 709550 to disk at time=7 seconds. Memory usage: 77856768
Writing game id: 575750 to disk at time=7 seconds. Memory usage: 77856768
Writing game id: 651950 to disk at time=7 seconds. Memory usage: 77856768
Writing game id: 685350 to disk at time=8 seconds. Memory usage: 77856768
Writing game id: 724150 to disk at time=9 seconds. Memory usage: 77856768
Writing game id: 522250 to disk at time=8 seconds. Memory usage: 77856768
Writing game id: 610350 to disk at time=10 seconds. Memory usage: 77856768
Writing game id: 645050 to disk at time=9 seconds. Memory usage: 77856768
Writing game id: 716950 to disk at time=9 seconds. Memory usage: 77856768
Writing game id: 672750 to disk at time=10 seconds. Memory usage: 77856768
Writing game id: 568650 to disk at time=11 seconds. Memory usage: 77856768
Writing game id: 668650 to disk at time=11 seconds. Memory usage: 77856768
Writing game id: 417950 to disk at time=11 seconds. Memory usage: 77856768
Writing game id: 497950 to disk at time=13 seconds. Memory usage: 77856768
Writing game id: 567950 to disk at time=12 seconds. Memory usage: 77856768
Writing game id: 692350 to disk at time=13 seconds. Memory usage: 77856768
Writing game id: 450950 to disk at time=13 seconds. Memory usage: 77856768
Writing game id: 452750 to disk at time=14 seconds. Memory usage: 77856768
Writing game id: 666450 to disk at time=14 seconds. Memory usage: 77856768
Writing game id: 754550 to disk at time=15 seconds. Memory usage: 77856768
Writing game id: 659050 to disk at time=15 seconds. Memory usage: 77856768
Writing game id: 712350 to disk at time=15 seconds. Memory usage: 77856768
Writing game id: 719250 to disk at time=16 seconds. Memory usage: 77856768
Writing game id: 529250 to disk at time=15 seconds. Memory usage: 77856768
Writing game id: 685150 to disk at time=17 seconds. Memory usage: 77856768
Writing game id: 736450 to disk at time=17 seconds. Memory usage: 77856768
Writing game id: 252750 to disk at time=17 seconds. Memory usage: 77856768
Writing game id: 719150 to disk at time=17 seconds. Memory usage: 77856768
Writing game id: 461150 to disk at time=18 seconds. Memory usage: 77856768
Writing game id: 699450 to disk at time=18 seconds. Memory usage: 77856768
Writing game id: 523550 to disk at time=18 seconds. Memory usage: 77856768
Writing game id: 451050 to disk at time=20 seconds. Memory usage: 77856768
Writing game id: 768350 to disk at time=19 seconds. Memory usage: 77856768
Writing game id: 724650 to disk at time=20 seconds. Memory usage: 77856768
Writing game id: 676550 to disk at time=21 seconds. Memory usage: 77856768
Writing game id: 730850 to disk at time=21 seconds. Memory usage: 77856768
Writing game id: 558250 to disk at time=22 seconds. Memory usage: 77856768
Writing game id: 674750 to disk at time=22 seconds. Memory usage: 77856768
Writing game id: 695450 to disk at time=22 seconds. Memory usage: 77856768
Writing game id: 682950 to disk at time=22 seconds. Memory usage: 77856768
Writing game id: 706450 to disk at time=24 seconds. Memory usage: 77856768
Writing game id: 546450 to disk at time=24 seconds. Memory usage: 77856768
Writing game id: 575350 to disk at time=24 seconds. Memory usage: 77856768
Writing game id: 616550 to disk at time=25 seconds. Memory usage: 77856768
Writing game id: 648250 to disk at time=26 seconds. Memory usage: 77856768
Writing game id: 763750 to disk at time=25 seconds. Memory usage: 77856768
Writing game id: 613850 to disk at time=26 seconds. Memory usage: 77856768
Writing game id: 645450 to disk at time=25 seconds. Memory usage: 77856768
Writing game id: 695950 to disk at time=33 seconds. Memory usage: 77856768
Writing game id: 661050 to disk at time=27 seconds. Memory usage: 77856768
Writing game id: 461050 to disk at time=27 seconds. Memory usage: 77856768
Writing game id: 693150 to disk at time=29 seconds. Memory usage: 77856768
Thanks!
原文:https://stackoverflow.com/questions/13961322
最满意答案
我已经尝试过由avo提供的实现 - 但它没有通过所有的测试。 我的意思是它提供了基本的行为,但在更复杂的情况下会失败(如多次投掷,重新夺回等)。
作为Theraot.Core的一部分,我以这样的方式创建了这个类的后端端口,它可以在现代的Mono,旧的Mono(2.6之前的版本)以及2.0到4.0之间的任何Microsoft .NET中工作。
*:用Miguel de Icaza的小技巧:)
下面的代码目前仅在Feature分支上,它最终将移动到主分支(以及.NET 2.0的Task),此时它将通过Theraot.Core nuget提供 。 我将它留在这里以防万一有人需要它。
如果您发现任何问题,欢迎在项目的github(上面链接)上的问题跟踪器上提供错误报告。
#if NET20 || NET30 || NET35 || NET40 using System.Reflection; namespace System.Runtime.ExceptionServices { /// <summary> /// The ExceptionDispatchInfo object stores the stack trace information and Watson information that the exception contains at the point where it is captured. The exception can be thrown at another time and possibly on another thread by calling the ExceptionDispatchInfo.Throw method. The exception is thrown as if it had flowed from the point where it was captured to the point where the Throw method is called. /// </summary> public sealed class ExceptionDispatchInfo { private static FieldInfo _remoteStackTraceString; private Exception _exception; private object _stackTraceOriginal; private object _stackTrace; private ExceptionDispatchInfo(Exception exception) { _exception = exception; _stackTraceOriginal = _exception.StackTrace; _stackTrace = _exception.StackTrace; if (_stackTrace != null) { _stackTrace += Environment.NewLine + "---End of stack trace from previous location where exception was thrown ---" + Environment.NewLine; } else { _stackTrace = string.Empty; } } /// <summary> /// Creates an ExceptionDispatchInfo object that represents the specified exception at the current point in code. /// </summary> /// <param name="source">The exception whose state is captured, and which is represented by the returned object.</param> /// <returns>An object that represents the specified exception at the current point in code. </returns> public static ExceptionDispatchInfo Capture(Exception source) { if (source == null) { throw new ArgumentNullException("source"); } return new ExceptionDispatchInfo(source); } /// <summary> /// Gets the exception that is represented by the current instance. /// </summary> public Exception SourceException { get { return _exception; } } private static FieldInfo GetFieldInfo() { if (_remoteStackTraceString == null) { // --- // Code by Miguel de Icaza FieldInfo remoteStackTraceString = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); // MS.Net if (remoteStackTraceString == null) remoteStackTraceString = typeof(Exception).GetField("remote_stack_trace", BindingFlags.Instance | BindingFlags.NonPublic); // Mono pre-2.6 // --- _remoteStackTraceString = remoteStackTraceString; } return _remoteStackTraceString; } private static void SetStackTrace(Exception exception, object value) { FieldInfo remoteStackTraceString = GetFieldInfo(); remoteStackTraceString.SetValue(exception, value); } /// <summary> /// Throws the exception that is represented by the current ExceptionDispatchInfo object, after restoring the state that was saved when the exception was captured. /// </summary> public void Throw() { try { throw _exception; } catch (Exception exception) { GC.KeepAlive(exception); var newStackTrace = _stackTrace + BuildStackTrace(Environment.StackTrace); SetStackTrace(_exception, newStackTrace); throw; } } private string BuildStackTrace(string trace) { var items = trace.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var newStackTrace = new Text.StringBuilder(); var found = false; foreach (var item in items) { // Only include lines that has files in the source code if (item.Contains(":")) { if (item.Contains("System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()")) { // Stacktrace from here on will be added by the CLR break; } if (found) { newStackTrace.Append(Environment.NewLine); } found = true; newStackTrace.Append(item); } else if (found) { break; } } var result = newStackTrace.ToString(); return result; } } } #endif
I have experimented with the implementation provided by avo - yet it doesn't pass all the tests. By that I mean that it provides the basic behaviour but will fail in more complex cases (such as multiple throwing, recapturing, etc...).
As part of Theraot.Core I have made a back port of this class in such way that it will work in modern Mono, old Mono (pre 2.6*) and any Microsoft .NET from 2.0 to 4.0.
*: With a little tip from Miguel de Icaza :)
The code below is currently only on the Feature branch, it will eventually move to the master branch (along with Task for .NET 2.0 :), at which point it will available via the Theraot.Core nuget. I'm leaving it here in case somebody needs it sooner.
Bug reports are welcome on the issue tracker at the project's github (linked above), if you find any.
#if NET20 || NET30 || NET35 || NET40 using System.Reflection; namespace System.Runtime.ExceptionServices { /// <summary> /// The ExceptionDispatchInfo object stores the stack trace information and Watson information that the exception contains at the point where it is captured. The exception can be thrown at another time and possibly on another thread by calling the ExceptionDispatchInfo.Throw method. The exception is thrown as if it had flowed from the point where it was captured to the point where the Throw method is called. /// </summary> public sealed class ExceptionDispatchInfo { private static FieldInfo _remoteStackTraceString; private Exception _exception; private object _stackTraceOriginal; private object _stackTrace; private ExceptionDispatchInfo(Exception exception) { _exception = exception; _stackTraceOriginal = _exception.StackTrace; _stackTrace = _exception.StackTrace; if (_stackTrace != null) { _stackTrace += Environment.NewLine + "---End of stack trace from previous location where exception was thrown ---" + Environment.NewLine; } else { _stackTrace = string.Empty; } } /// <summary> /// Creates an ExceptionDispatchInfo object that represents the specified exception at the current point in code. /// </summary> /// <param name="source">The exception whose state is captured, and which is represented by the returned object.</param> /// <returns>An object that represents the specified exception at the current point in code. </returns> public static ExceptionDispatchInfo Capture(Exception source) { if (source == null) { throw new ArgumentNullException("source"); } return new ExceptionDispatchInfo(source); } /// <summary> /// Gets the exception that is represented by the current instance. /// </summary> public Exception SourceException { get { return _exception; } } private static FieldInfo GetFieldInfo() { if (_remoteStackTraceString == null) { // --- // Code by Miguel de Icaza FieldInfo remoteStackTraceString = typeof(Exception).GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); // MS.Net if (remoteStackTraceString == null) remoteStackTraceString = typeof(Exception).GetField("remote_stack_trace", BindingFlags.Instance | BindingFlags.NonPublic); // Mono pre-2.6 // --- _remoteStackTraceString = remoteStackTraceString; } return _remoteStackTraceString; } private static void SetStackTrace(Exception exception, object value) { FieldInfo remoteStackTraceString = GetFieldInfo(); remoteStackTraceString.SetValue(exception, value); } /// <summary> /// Throws the exception that is represented by the current ExceptionDispatchInfo object, after restoring the state that was saved when the exception was captured. /// </summary> public void Throw() { try { throw _exception; } catch (Exception exception) { GC.KeepAlive(exception); var newStackTrace = _stackTrace + BuildStackTrace(Environment.StackTrace); SetStackTrace(_exception, newStackTrace); throw; } } private string BuildStackTrace(string trace) { var items = trace.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var newStackTrace = new Text.StringBuilder(); var found = false; foreach (var item in items) { // Only include lines that has files in the source code if (item.Contains(":")) { if (item.Contains("System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()")) { // Stacktrace from here on will be added by the CLR break; } if (found) { newStackTrace.Append(Environment.NewLine); } found = true; newStackTrace.Append(item); } else if (found) { break; } } var result = newStackTrace.ToString(); return result; } } } #endif
相关问答
更多-
我们已经开始以带外方式发布越来越多的框架组件,这样您就不必构建设置,甚至不必等待下一版本的.NET Framework。 话虽这么说,来自NuGet的程序集就像你的应用程序集。 这意味着,使用NGEN并将其添加到GAC 可以提高您的启动性能。 与往常一样,您应该测量它是否有所作为。 GACing和NGENing增加了部署的复杂性,应该通过增加值来抵消。 We've started to ship more and more framework components in an out-of-band fas ...
-
组件Microsoft.Threading.Tasks和Microsoft.Threading.Tasks.Extensions仍然引用System.Runtime和System.Threading.Tasks v1.5.11.0。 没有bindingRedirect , Microsoft.*程序集将尝试加载旧版本的System.*组件,这将失败。 The assemblies Microsoft.Threading.Tasks and Microsoft.Threading.Tasks.Extensio ...
-
您的CI服务器必须使用最新的msbuild.exe(来自.net 4.5) Your CI server must use the latest msbuild.exe (from .net 4.5)
-
我已经尝试过由avo提供的实现 - 但它没有通过所有的测试。 我的意思是它提供了基本的行为,但在更复杂的情况下会失败(如多次投掷,重新夺回等)。 作为Theraot.Core的一部分,我以这样的方式创建了这个类的后端端口,它可以在现代的Mono,旧的Mono(2.6之前的版本)以及2.0到4.0之间的任何Microsoft .NET中工作。 *:用Miguel de Icaza的小技巧:) 下面的代码目前仅在Feature分支上,它最终将移动到主分支(以及.NET 2.0的Task),此时它将通过Thera ...
-
那么,我猜这个问题本身就解决了。 “破碎的”电脑1显然没有损坏,或者已经不是神奇的了,电脑2现在已经修好了,然后疯狂地卸载了一切与.NET相关的东西并重新安装了Visual Studio。 我现在无法正确地诊断出这个问题的根源,这真令人失望,但我只能忍受这一点。 Well, I guess the problem resolved itself. "Broken" computer 1 apparently wasn't broken or was and magically isn't anymore a ...
-
为什么NuGet会根据您的起点以不同方式解析版本?(Why does NuGet resolve versions differently depending on where you start?)[2021-12-03]
是不是NuGet应该将包解析为兼容性边界内的最新版本? 不会.NuGet实际上会选择最低的主要/次要版本和最高的补丁版本 。 这样做的理由是因为主要版本可能会引入重大变化,次要版本可能会引入新功能(因此引入错误的可能性更高),但补丁版本只能修复错误。 如果这是默认行为,那么这可以覆盖它吗? 由于您的库需要这些库的特定版本,因此只需将version属性添加到nuspec中的相应dependency节点即可。 isn't NuGet supposed to resolve packages to the mos ... -
异步定位包版本(Async Targeting Pack Versions)[2024-01-08]
Microsoft.Bcl.Async是Microsoft.Bcl.Async的替代品。 除非您更改其名称,否则在NuGet上取代另一个包并不常见。 在这种特殊情况下,我相信AsyncTargetingPack (错误地)列出时没有“预发布”标志,然后Microsoft的团队在Bcl.Async采用了更广泛的方法(支持更多场景)。 Bcl.Async在我的脑海中取代了AsyncTargetingPack几个月前的第一次(pre)发布,但有两个原因造成了一些混乱:1)团队仍然将Bcl.Async称为“异步目标 ... -
添加Microsoft.Bcl.Async后,其他项目无法识别我的dll(After adding Microsoft.Bcl.Async other projects don't recognize my dll)[2022-04-23]
该解决方案是将Microsoft BCL构建组件添加到引用使用Microsoft BCL异步的项目的所有项目。 The solution is add Microsoft BCL Build Components to all the projects referencing the project that use Microsoft BCL Async. -
我最终使用了来自@StephenCleary的答案,而我将我的PCL定位到.NET 4.0,并使用了Bcl.Async包。 谢谢! I ended up using the answer from @StephenCleary, whereas I targeted my PCL to .NET 4.0, and used the Bcl.Async pack. Thanks!
-
来自http://michaelmairegger.wordpress.com/2012/09/19/cannot-find-all-types-required-by-the-async-modifier/ : 此问题的解决方案是将以下nuGet包引用到要使用“async”和“await”关键字的所有项目中。 Microsoft.CompilerServices.AsyncTargetingPack 因此,右键单击References ,然后选择Manage NuGet Packages... ,然后在线 ...