我在Visual Studio中遇到了一些奇怪的错误,找不到头或尾。我正在用C#编写一些后端代码,它联系第三方API来检索数据。有问题的代码,一个单独的类,是一个更大的解决方案的一部分,但一定是问题所在,因为在不使用此类时不会发生遇到的错误。
计算机设置:
-
Visual Studio 2013,更新4
-
Windows 10,预览版10041
遇到错误
昨天,应用程序在调试时开始表现得很奇怪。第一个错误我记不清了,但大致是";坏的";或";损坏的存储器";。
在不更改程序的情况下,我还可能遇到FatalExecutionEngineError异常,该异常将在尝试运行程序后立即抛出(它没有到达程序主条目第一行的第一个断点。奇怪!
编辑:看起来像这样:
托管调试助手"FatalExecutionEngineError"在"PathRedacted\whatsfordinary\whatsforminary\bin\Debug\whatsfoldinary.vhost.exe"中检测到问题。
附加信息:运行时遇到致命错误。错误的地址位于线程0x11ac上的0x613e4379。错误代码为0xc0000005。此错误可能是CLR或用户代码的不安全或不可验证部分中的错误。此错误的常见来源包括COM互操作或PInvoke的用户封送处理错误,这些错误可能会损坏堆栈。
最后我重新启动了我的电脑,因为这一切都很奇怪。问题一直解决到今天。
现在我似乎根本无法运行该程序;在运行该程序时,vshost32.exe只是崩溃。我没有收到任何错误消息或任何提示问题所在的信息。
故障排除步骤
- 重新启动我的计算机-没有更改,vshost32.exe在执行时崩溃
- 超过了使用有问题的类的两行——程序运行良好
- 尝试以";释放";而不是";调试"。-程序似乎运行得很好,尽管我无法测试到底。(该类还没有完全完成,我不想向有问题的API发送垃圾邮件)
- 尝试在另一台运行Windows 7和Visual Studio 2012的计算机上运行该程序。-程序似乎运行良好
在这一点上,我很失落。我不知道问题可能在哪里。不幸的是,源代码由近200行组成,但由于我不知道,我将全部发布。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Specialized;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace whatsfordinner {
public class eTilbudRetriever {
//Web method names
readonly String Get = "GET";
readonly String Post = "POST";
readonly String Update = "UPDATE";
readonly String Delete = "DELETE";
//Parameter identifiers
readonly String ParamApiKey = "api_key";
readonly String ParamLatitude = "r_lat";
readonly String ParamLongitude = "r_lng";
readonly String ParamRadius = "r_radius";
readonly String ParamLimit = "limit";
readonly String ParamOffset = "offset";
//Parameter values
String Latitude = "57.051188"; //Aalborg coordinates
String Longitude = "9.922371";
String Radius = "800000"; //Radius in meters (800km)
String Limit = "48"; // Results per query
//Custom header identifiers
readonly String HeaderXToken = "X-Token";
readonly String HeaderXSignature = "X-Signature";
//Custom header values
readonly String ContentType = "application/json";
//Web Addresses
readonly String HostAddress = "https://api.etilbudsavis.dk/v2/";
readonly String Sessions = "sessions";
readonly String Stores = "stores";
readonly String Offers = "offers";
readonly String Dealers = "dealers";
//Keys
readonly String ApiKey = "<Redacted>";
readonly String ApiSecret = "<Redacted>";
String XToken; //Same as a Session Token in documentation
String XSignature; //Same as a Session Signature in documentation
public eTilbudRetriever() {
//Create a body consisting of the API key
List<KeyValuePair<String, String>> body = new List<KeyValuePair<String, String>>();
body.Add(new KeyValuePair<String, String>(ParamApiKey, ApiKey));
//Send request to create a new session
String response = SendWebRequest(Post, Sessions, body);
//Get the Session Token from the response
dynamic json = JObject.Parse(response);
XToken = json.token;
//Save the Session Signature as well (SHA256 version of API Secret combined with Session Token)
XSignature = ConvertToSha256(ApiSecret + XToken);
}
public void GetDealersList() {
GetList(Dealers);
}
public void GetStoresList() {
GetList(Stores);
}
public void GetOffersList() {
GetList(Offers);
}
private void GetList(string target) {
List<String> resultSet = new List<String>();
String result;
int offset = 0;
//Add desired parameters as headers for the eTilbudsavisen API
List<KeyValuePair<String, String>> query = new List<KeyValuePair<String, String>>();
query.Add(new KeyValuePair<String, String>(ParamLatitude, Latitude));
query.Add(new KeyValuePair<String, String>(ParamLongitude, Longitude));
query.Add(new KeyValuePair<String, String>(ParamRadius, Radius));
query.Add(new KeyValuePair<String, String>(ParamLimit, Limit));
query.Add(new KeyValuePair<String, String>(ParamOffset, offset.ToString()));
//Retrieve a result through the request
result = SendWebRequest(Get, target, query);
/*
* If result is valid, add it to the set of valid results.
* Keep sending requests and increase the offset to avoid duplicated results
* Stop when returned results are no longer valid
*/
while (!String.IsNullOrEmpty(result)) {
resultSet.Add(result);
offset += Int32.Parse(Limit);
query[query.Count-1] = new KeyValuePair<String, String>(ParamOffset, offset.ToString());
result = SendWebRequest(Get, target, query);
}
}
private String SendWebRequest(String method, String extension, List<KeyValuePair<String, String>> arguments) {
try {
String finalAddress = HostAddress + extension;
//Add query to Address (if applicable)
if (method.Equals(Get)) {
finalAddress += '?';
finalAddress += arguments[0].Key + '=' + arguments[0].Value;
for (int i = 1; i < arguments.Count; i++) {
finalAddress += '&' + arguments[i].Key + '=' + arguments[i].Value;
}
}
//Create request and set mandatory header properties
var request = (HttpWebRequest)WebRequest.Create(finalAddress);
request.Method = method;
request.ContentType = ContentType;
request.Accept = ContentType;
//If a Session Token and Signature are available (= After session create), add as headers
if (!String.IsNullOrEmpty(XToken)) {
request.Headers.Add(HeaderXToken, XToken);
request.Headers.Add(HeaderXSignature, XSignature);
}
//Create JSON string containing the desired body arguments (if applicable)
if (method.Equals(Post)) {
//Write body to API
using (var writer = new StreamWriter(request.GetRequestStream())) {
writer.Write(MakeJsonBody(arguments));
}
}
//get response as a JSON object in string format
var response = (HttpWebResponse)request.GetResponse();
return new StreamReader(response.GetResponseStream()).ReadToEnd();
} catch (UriFormatException e) {
Console.WriteLine(e.ToString());
return null;
} catch (WebException e) {
Console.WriteLine(e.ToString());
return null;
}
}
private String ConvertToSha256(String text) {
byte[] bytes = Encoding.UTF8.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash) {
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
private String MakeJsonBody(List<KeyValuePair<String, String>> arguments) {
String json = "{";
foreach (KeyValuePair<String, String> kv in arguments) {
json += """ + kv.Key + "": "" + kv.Value + """;
if (arguments.IndexOf(kv) != arguments.Count() - 1) {
json += ", ";
}
}
json += "}";
return json;
}
}
}
在Main
中,这是相对于类执行的内容。从解决方案中删除这些行时,程序运行良好。
eTilbudRetriever retriever = new eTilbudRetriever();
retriever.GetDealersList();
Windows 10,预览版10041
这是你的程序崩溃的唯一可能原因。没有其他程序,你的代码不会做任何危险的事情,Newtonsoft.Json已经被数百万程序以各种可能的方式猛烈抨击。您正在使用.NET Framework(v4.6)和操作系统的测试版。感谢所有Microsoft客户帮助调试此新软件,您的问题不是我们必须解决的问题。希望,FEEE崩溃是极其恶劣和难以调试的。
应该做的是向Microsoft提交崩溃进程的小型转储,这样他们就可以修复潜在的错误。不管是什么,你的问题都没有任何线索也许这是x64抖动的完全重写(项目代码名RyuJit)。它现在没有错误的可能性很小,这样的错误肯定会让你的程序崩溃。不过,这只是一个疯狂的猜测。
Microsoft免费提供这些预览。他们的根本意图是在产品发货之前把bug清除掉。应该在夏天左右的某个地方发生。只有这样,他们才能有一些信心,一旦他们发货,他们的支持电话线就不会过载。测试版的更新来得又快又猛,有6个CTP版本的.NET 4.6。这是前所未有的,通常不超过3个。至少有一部分是VS2015的测试版,该版本中有很多新内容。你没有使用的,这也没有帮助。
你的角色是作为一个免费的测试人员。这往往与你的另一个角色——以编写和调试代码为生的程序员——不兼容。你的代码,不是别人的。当你无法承受这样的困境时,唯一明智的做法就是取消订阅该测试版程序。将您的机器恢复到已知的良好版本的框架和操作系统。现在是.NET 4.5.2和Windows 8.1