我正在设计一个类,我希望在主线程完成配置之后只读它,即"冻结"它.Eric Lippert将这种冰棍称为不变性.冻结后,可以同时访问多个线程进行读取.
我的问题是如何以线程安全的方式编写这个实际有效的方法,即不要试图不必要地聪明.
尝试1:
public class Foobar
{
private Boolean _isFrozen;
public void Freeze() { _isFrozen = true; }
// Only intended to be called by main thread, so checks if class is frozen. If it is the operation is invalid.
public void WriteValue(Object val)
{
if (_isFrozen)
throw new InvalidOperationException();
// write ...
}
public Object ReadSomething()
{
return it;
}
}
Run Code Online (Sandbox Code Playgroud)
Eric Lippert似乎认为这篇文章可以.我知道写入具有释放语义,但据我所知,这仅适用于排序,并不一定意味着所有线程都会在写入后立即看到该值.谁能证实这一点?这意味着这个解决方案不是线程安全的(当然这可能不是唯一的原因).
尝试2:
以上,但Interlocked.Exchange用于确保实际发布的值:
public …Run Code Online (Sandbox Code Playgroud) 通常,使用WebRequest编写类似这样的代码来下载一些数据.
using(WebResponse resp = request.GetResponse()) // WebRequest request...
using(Stream str = resp.GetResponseStream())
; // do something with the stream str
Run Code Online (Sandbox Code Playgroud)
现在,如果抛出WebException,WebException会引用WebResponse对象,该对象可能会或可能不会调用Dispose(取决于发生异常的位置,或者响应类的实现方式) - 我不知道.
我的问题是如何处理这个问题.是否应该编写一个非常防御性的编码,并在WebException对象中处理响应(这有点奇怪,因为WebException不是IDisposable).或者是否应该忽略这一点,可能访问已处置的对象或从不处置IDisposable对象?WebException.Response的MSDN文档中给出的示例完全不合适.
我经常觉得必须实现一个接口是非常分心的,因为我需要一次方法调用.我必须在其他地方创建一个类,实现接口等.
Java有一个名为Anonymous Classes的功能,允许用户实现"内联"接口.我的问题是:你能想到用C#在现有语法中完成类似事情的最好方法是什么(我意识到"最好"是主观的).我正在寻找好的语法,不一定是性能.
我在C#中将以下内容实现为POC :
特定
interface IFoobar
{
Boolean Foobar(String s);
}
IFoobar foo = Implement.Interface<IFoobar>(new {
Foobar = new Func<String, Boolean>(s => s == "foobar")
});
Run Code Online (Sandbox Code Playgroud)
这使用匿名对象和一些反射/发射来实现IFoobar接口(忽略属性,泛型方法和重载).但是,我不是这些new Func<...>东西的粉丝,但离不开它们.
环顾四周,我注意到了一个名为Impromptu Interface的库,但是它的语法并没有给支持方法留下深刻的印象.
有一种"更好"的方式吗?
编辑:我不是在寻找Java与C#的火焰战争.
我有兴趣听ETW(Windows的事件跟踪)TPL事件,特别是我想知道什么时候Task开始以及何时停止.
这是我用于测试的示例程序:
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication10
{
class Listener : EventListener
{
private static readonly Guid tplGuid = new Guid("2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5");
protected override void OnEventSourceCreated(EventSource eventSource)
{
Console.WriteLine("Got guid: " + eventSource.Guid);
EnableEvents(eventSource, EventLevel.LogAlways);
}
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
Console.WriteLine("Event: " + eventData.EventId);
}
}
class Program
{
static void Main(string[] args)
{
using (var listener = new Listener())
{
Action doIt = null;
doIt …Run Code Online (Sandbox Code Playgroud) XmlWriter在编写属性时,有没有办法使输出单引号而不是双引号?
我没有兴趣在XmlTextWriter其中有一个QuoteChar属性(不奇怪的一部分XmlWriterSettings).除了包装一个之外,覆盖一些现有的编写器类并不可行.
询问的原因:我在html数据属性中输出json,因为json引用字符是"这很容易导致数据爆炸,因为"被转义为" 到处.如果我可以使用单引号来启动属性值,则json中的双引号不需要转义.
我输出(X)HTML,并根据问题,比如这一个,单引号是法律来界定的属性值.
我很确定没有(理智的)这样做,但谁知道我错过了什么.
经过一段时间的谷歌搜索后,我还没有找到任何关于HttpContext的线程安全性的权威,确凿的信息.
我正在看一个场景,例如:
public class AsyncHandler : IAsyncHttpHandler
{
void BeginProcessRequest(...)
{
// Spawn some tasks in parallel, provide them with current HttpContext as argument.
}
void EndProcessRequest(...) {...}
}
Run Code Online (Sandbox Code Playgroud)
My(io bound)并行任务可能希望同时访问HttpContext.
看看各个帖子似乎这是安全的,但是,我想要一些实际的证据.当然MSDN给出了通常的"静态线程安全等",但除了我必须假设它不是线程安全之外,这没有任何帮助.
我在StackOverflow上看过各种帖子(比如这里,或者这里,或者这里),但这个问题没有真正的答案.
使用.NET 4.5中的所有异步工作,如果HttpContext不是线程安全的话,这似乎有点奇怪,但是,如果确实不是这样,有没有办法让它成功呢?我能想到:
但这一切都感觉有点糟糕和太多的工作.
编辑:在更详细地研究这个,以及稍后的一些反思后,我相信它实际上并不重要HttpContext不是线程安全的.我在这篇博文中详述了这一点.要点是在ASP.NET中使用正确的SynchronizationContext可确保一次只能有一个线程访问上下文.
.net ×5
c# ×5
asp.net ×1
dynamic ×1
escaping ×1
etw ×1
httpcontext ×1
idisposable ×1
interface ×1
json ×1
quotes ×1
webresponse ×1
xmlwriter ×1