比较旧的错误处理方式和新的错误处理方式,通过使用异常过滤器,使用过滤器对我来说到底有什么好处,什么时候应该使用它?在什么情况下我可以很好地利用这个新功能?
我已经阅读了有关展开堆栈的信息,但仍然不明白我们无法以旧方式处理该问题的情况。请像我5岁一样解释一下。
try
{
Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex) when (ex.Code == 42)
{
Console.WriteLine("Error 42 occurred");
}
Run Code Online (Sandbox Code Playgroud)
与
try
{
Foo.DoSomethingThatMightFail(null);
}
catch (MyException ex)
{
if (ex.Code == 42)
Console.WriteLine("Error 42 occurred");
else
throw;
}
Run Code Online (Sandbox Code Playgroud)
我知道这个问题还有其他版本,问题是,这个问题提到了我实际上找不到的好处,例如。
异常过滤器比捕获和重新抛出更可取,因为它们不会损害堆栈。如果异常后来导致堆栈被转储,您可以看到它最初来自哪里,而不仅仅是最后一次被重新抛出的位置。
经过一些测试后,我没有看到两者之间的区别,我仍然从重新抛出的地方看到异常。所以,或者信息没有得到确认,我不理解异常过滤器(这就是我问的原因),或者我做错了(如果我错了,也请纠正我)。
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email@domain.com";
}
Run Code Online (Sandbox Code Playgroud)
然后:
try
{
throw new specialException();
//throw new …
Run Code Online (Sandbox Code Playgroud) 如何正确使用一个SqlConnection
对象进行多个查询?
SqlConnection connection = new SqlConnection(connString);
static void SqlQuery(SqlConnection conn, string cmdString)
{
using (conn)
{
if (conn.State != ConnectionState.Open)
{
conn.Close();
conn.Open();
}
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = cmdString;
cmd.ExecuteNonQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
SqlQuery
第一次调用后的函数抛出System.InvalidOperationException
"ConnectionString属性未初始化"
我想在本地文化中输出一个时间跨度,将其作为csv导入Excel中.时间跨度包含毫秒.
与英国文化,这意味着,例如00:00:01.2345678
与德国文化,这应该是00:00:01,2345678
(逗号而不是点)
但无论我为CultureInfo对象尝试哪种设置,我都无法让它工作:
TimeSpan t = new TimeSpan(12345678);
var cul = CultureInfo.GetCultureInfo("de");
// cul.DateTimeFormat.FullTimeSpanPositivePattern == "d':'h':'mm':'ss','FFFFFFF";
// (note the comma)
Console.WriteLine(String.Format(cul, "{0}", t));
// expected: "00:00:01,2345678" (with ,)
// actual: "00:00:01.2345678" (with .)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我甚至无法分辨CultureInfo类的哪些属性定义了这个.这是硬编码的吗?
我知道我可以明确地定义输出格式:`String.Format("{0:hh \:mm \:ss \,FFFFFFF}",t)
但有没有办法使用a IFormatProvider
,所以c#将使用给定的文化?
我正在尝试更新本文的代码,以允许我创建(和使用)基于 ECC 的自签名证书,并使用它进行基本的签名和验证( ECDSA)。
根据这篇文章,我需要使用the more standard id-ecc
类型
cryptography public-key .net-core .net-4.6 self-signed-certificate
IsAbstract 似乎不存在。它去哪儿了?
[TestMethod]
public void IsAbstractBaseClass()
{
Type type = typeof(ViewModelBase);
Assert.IsTrue(type.IsAbstract);
}
Run Code Online (Sandbox Code Playgroud) 我试图使用.NET 4.6 CLR启动并运行MVC 6 Web应用程序,但是我收到以下类型的错误:
The dependency Microsoft.AspNet.Loader.IIS 1.0.0-beta5 in project TestDeployProject does not support framework .NETFramework,Version=v4.6.
Run Code Online (Sandbox Code Playgroud)
project.json:
{
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-beta5",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta5",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta5",
"Microsoft.Framework.DependencyInjection.Abstractions": "1.0.0-beta5",
"Microsoft.AspNet.Mvc": "6.0.0-beta5"
},
"frameworks": {
"net46": { }
},
}
Run Code Online (Sandbox Code Playgroud)
根据这篇博文,.NET 4.6目标框架可以与ASP.NET 5一起使用.
我究竟做错了什么?
基于这个问题(新Exception filter
功能提供了哪些好处?).
该声明:
异常过滤器比捕获和重新抛出更可取,因为它们可以保持堆栈不受破坏.如果稍后的异常导致堆栈被转储,您可以看到它最初来自哪里,而不仅仅是它重新抛出的最后一个位置.
做一些测试后,我没有看到这两个之间的区别,新与旧,我还看到有人的地方例外重新抛出.所以,或者信息未被确认,我不理解异常过滤器(这就是我要问的原因),或者我做错了.你能解释一下为什么这个动作过滤器有优势吗?
class specialException : Exception
{
public DateTime sentDateTime { get; } = DateTime.Now;
public int code { get; } = 0;
public string emailsToAlert { get; } = "email@domain.com";
}
Run Code Online (Sandbox Code Playgroud)
然后:
try
{
throw new specialException(); //line 16
throw new Exception("Weird exception");
//int a = Int32.Parse("fail");
}
catch (specialException e) when(e.code == 0)
{
WriteLine("E.code 0");
throw; // <-Line 23
}
catch (FormatException e)
{
WriteLine("cond1 " + e.GetBaseException().Message+" …
Run Code Online (Sandbox Code Playgroud) 我有从重写应用程序ASP.Net Core
来ASP.Net 4.6.1
和我送的应用程序的核心版本Json
数据Bugzilla的处理,它工作正常。它发送数据并很快得到响应。应用程序 4.6.1 版本中的相同代码位于并挂起发送命令。我可以进入 BugZilla 并看到它获取了数据并生成了错误,但即使在 15 分钟后应用程序也没有进展。我是 Task 的新手并通过 Json 发送数据,所以我不确定为什么会遇到这个问题。永远不会返回任何错误,在调试模式下,我可以逐步完成所有操作,并知道它正在排队等待SendAsync
。我做错了什么在 4.6.1 中打破了这个?
private static async Task<int> LogToBugZilla(string Component, Exception ex)
{
var ErrorSummary = "Auto Error Logging: " + ex.Message + " " + ex.InnerException.Message;
var BugData = new Dictionary<string, string>
{
{ "Bugzilla_api_key", ConfigurationManager.AppSettings["BugZillaAPIKey"] },
{ "product", "Job Site" },
{ "component", Component },
{ "version", ConfigurationManager.AppSettings["AppVersion"] },
{ "summary", ErrorSummary },
{ "op_sys", "All" },
{ "platform", …
Run Code Online (Sandbox Code Playgroud) 我有一个针对.NET Framework 4.6的应用程序
当我在只安装了.NET 4.5的机器上运行它时,它会启动,并且大部分工作正常...我只是得到了一些非常奇怪的无用的运行时错误,例如
"找不到方法:'!! 0 [] System.Array.Empty()'"
(其中包括)并不是很远,提醒我问题是.NET运行时.
我可以调用一个在启动时在.NET 4.5下不起作用的方法,捕获错误,并重新抛出一个有用的错误消息.在某些方面,这将是最具体的 - 只需检查我需要使用的函数,如果.NET的下一个版本有一个奇怪的无序版本号,测试$ expectedversion <= $ actualversion将会中断,而检查函数是否有效会没事的.
它只是感觉非常丑陋和凌乱.我不希望我的程序的启动例程必须做这种事情.它也很难测试,因为我的所有机器上都有.NET 4.6.
我可以检查注册表 - 除了注册表访问是4.5和4.6之间似乎已经发生变化的事实之外,我检查注册表设置的代码也会抛出无用的异常.我看到的注册表检查功能与已知的 .NET版本兼容,但具有非常特定的版本号,并且不会告诉我很多尚未存在的未知.NET版本.
那么 - 检查运行时环境是否与我编译的.NET版本相匹配的最佳方法是什么?
我有一个适用于4.5的信号器.升级到4.6后,它在Win 2008 R2上运行正常,但在Windows 2012上不起作用.
错误是:
System.InvalidOperationException: WebSockets is unsupported in the current application configuration. To enable this, set the following configuration switch in Web.config:
system.web
httpRuntime targetFramework="4.5"
system.web
For more information, see http://go.microsoft.com/fwlink/?LinkId=252465.
at
System.Web.Util.SynchronizationContextUtil.ValidateMode(SynchronizationContextMode currentMode, SynchronizationContextMode requiredMode, String specificErrorMessage)
at System.Web.HttpContext.AcceptWebSocketRequest(Func2 userFunc, AspNetWebSocketOptions options) at Microsoft.AspNet.SignalR.Transports.WebSocketTransport.AcceptWebSocketRequest(Func2 callback)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequestPostGroupRead(HostContext context, String groupsToken)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.FromMethodT1,T2,T3,TResult
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext()
--- End of stack …
Run Code Online (Sandbox Code Playgroud) 我读到的任何地方都应该用它ConfigureAwait(false)
来避免死锁和出于性能原因.我们正在使用ConfigureAwait
我们的应用程序.但是可能会删除ConfigureAwaits,因为它会导致不同的线程的执行上下文.
不同线程的执行上下文导致(有时)翻译问题.由于当前文化和currentUICulture中的集合文化无法在不同的执行上下文中访问.
我用下面的代码测试了一下.它没有任何性能差异.我知道这不是一个好的测试,因为这个简单的测试没有使用很多线程.
static async Task MyMethodAsync()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000; i++)
{
await Task.Delay(10);
await Task.Delay(10).ConfigureAwait(continueOnCapturedContext: false);
}
stopwatch.Stop();
Console.WriteLine("Await: " + stopwatch.Elapsed.ToString());
}
static async Task MyMethodAsyncNoAwait()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < 1000; i++)
{
await Task.Delay(10);
await Task.Delay(10);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed.ToString());
}
Run Code Online (Sandbox Code Playgroud)
我该如何正确测试?删除所有ConfigureAwaits是一个非常糟糕的主意吗?
我有一个实例,考虑到夏令时规则DateTimeOffset
,我需要在特定的TimeZone
(西欧标准时间)中添加 1 天(因此它可能会导致Offset
更改)。如果没有 3rd 方库,我该怎么做?
可验证示例:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject
{
[TestClass]
public class TimeZoneTests
{
[TestMethod]
public void DateTimeOffsetAddDays_DaylightSaving_OffsetChange()
{
var timeZoneId = "W. Europe Standard Time";
var utcTimestamp = new DateTimeOffset(2017, 10, 28, 22, 0, 0, TimeZoneInfo.Utc.BaseUtcOffset);
var weuropeStandardTimeTimestamp = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcTimestamp, timeZoneId);
Assert.AreEqual(new DateTime(2017, 10, 29), weuropeStandardTimeTimestamp.DateTime);
Assert.AreEqual(TimeSpan.FromHours(2), weuropeStandardTimeTimestamp.Offset);
var weuropeStandardTimeTimestampNextDay = AddDaysInTimeZone(weuropeStandardTimeTimestamp, 1, timeZoneId);
Assert.AreEqual(new DateTime(2017, 10, 30), weuropeStandardTimeTimestampNextDay);
Assert.AreEqual(TimeSpan.FromHours(1), weuropeStandardTimeTimestamp.Offset);
}
private DateTimeOffset AddDaysInTimeZone(DateTimeOffset timestamp, int days, string …
Run Code Online (Sandbox Code Playgroud) 我想要一个构造函数调用只允许有限范围的"扩展".假设我有这两个类:
public class Foo
{
public Foo(Extension ext)
{
// do something
}
}
public class Extension
{
public const string TXT = ".txt";
public const string XML = ".xml";
}
Run Code Online (Sandbox Code Playgroud)
因此,当另一个开发人员想要使用时,Foo
他只能使用Extension
类中的值来执行此操作,如下所示:
Foo foo = new Foo(Extension.TXT);
Run Code Online (Sandbox Code Playgroud)
但是当我尝试这样做时,我得到一个IDE错误说:"cannot convert from 'string' to '<ProjectName>.Extension'
.
作为一种"解决方法",我可以将我的Extension
课程改为:
public class Extension
{
public enum File
{
TXT,
XML
}
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
Foo foo = new Foo(Extension.File.TXT);
Run Code Online (Sandbox Code Playgroud)
哪个工作得很好但我不喜欢的是调用是一个更长的级别(类 - >枚举 - >元素而不是类 - >元素).
那么,问题是我的解决方法实际上是唯一有效,正确或最佳实践的解决方案吗?
.net-4.6 ×13
c# ×10
.net ×4
async-await ×2
exception ×2
.net-4.5 ×1
.net-core ×1
asp.net-core ×1
asp.net-mvc ×1
asynchronous ×1
c#-6.0 ×1
cryptography ×1
cultureinfo ×1
localization ×1
nuget ×1
performance ×1
project.json ×1
public-key ×1
signalr ×1
timespan ×1
timezone ×1
unit-testing ×1
websocket ×1