Encoding
从不同的线程使用相同的对象是否安全?
通过"使用"我的意思是,打电话Encoding.GetString()
,Encoding.GetBytes()
写一些XML与XmlWriter
(由类似于创建XmlWriter.Create(myStream, new XmlWriterSettings() { Encoding = myEncoding })
.
msdn网站声明"不保证所有实例成员都是线程安全的".
那么,如何安全地同时编写两个XML文档呢?(谢谢!!)
我希望sort
命令将所有字符都视为相等.
例如,当我这样做
$ echo -e 'TEST.b\nTESTa\nTESTc' | sort
TESTa
TEST.b
TESTc
Run Code Online (Sandbox Code Playgroud)
点被忽略了.
我想TEST.b
进入最后或第一个位置.但是,我在手册页中找不到合适的参数.
(我的版本sort
来自GNU核心实用程序).
我试图解析通过TCP发送到我的C#应用程序的XML消息.遗憾的是,协议无法更改,XML消息也没有分隔,也没有使用长度前缀.此外,字符编码不是固定的,但每条消息都以XML声明开头<?xml>
.问题是,如何使用C#一次读取一条XML消息.
到目前为止,我试图将TCP流中的数据读入一个字节数组并通过它来使用它MemoryStream
.问题是,缓冲区可能包含多个XML消息,或者第一条消息可能不完整.在这些情况下,我尝试使用XmlReader.Read
或解析它时会出现异常XmlDocument.Load
,但不幸的是,XmlException
这并不能让我区分问题(除了解析本地化的错误字符串).
我试着用XmlReader.Read
和计数的数量Element
和EndElement
节点.这样我就知道我什么时候读完第一条完整的XML消息.
但是,有几个问题.如果缓冲区尚未包含整个消息,我如何区分XmlException
实际无效的,格式不正确的消息?换句话说,如果在读取第一个根之前抛出异常EndElement
,我该如何决定是否中止连接错误,还是从TCP流中收集更多字节?
如果没有异常发生,则将XmlReader
其定位在根的开头EndElement
.铸造XmlReader
到IXmlLineInfo
给我当前LineNumber
和LinePosition
,但它是不直截了当地让其中的字节位置EndElement
真的结束.为了做到这一点,我将不得不字节数组转换为字符串(与XML声明中指定的编码),寻求LineNumber
,LinePosition
并转换回字节偏移.我尝试使用StreamReader.ReadLine
,但流阅读器不提供对当前字节位置的公共访问.
所有这些接缝都非常不优雅且不健壮.我想知道你是否有更好的解决方案的想法.谢谢.
编辑:我在问两个线程在没有正确同步的情况下并发访问相同数据时会发生什么(在此编辑之前,该点未明确表达).
我有一个关于C#编译器和JIT编译器执行的优化的问题.
请考虑以下简化示例:
class Example {
private Action _action;
private void InvokeAction() {
var local = this._action;
if (local != null) {
local();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请在示例中忽略读取_action
可能会产生缓存和过期值,因为没有volatile说明符或任何其他同步.那不是重点:)
是否允许编译器(或实际上是运行时的抖动)优化对局部变量的赋值,而是_action
从内存中读取两次:
class Example {
private Action _action;
private void InvokeAction() {
if (this._action != null) {
this._action(); // might be set to null by an other thread.
}
}
}
Run Code Online (Sandbox Code Playgroud)
NullReferenceException
当并行赋值将字段_action
设置为时,可能会抛出一个null
.
当然,在这个例子中,这样的"优化"没有任何意义,因为将值存储在寄存器中并因此使用局部变量会更快.但是在更复杂的情况下,是否可以保证无需重新读取内存中的值而按预期工作?
我有一个特殊的问题,实现我应该支持的自己的集合IBindingList
.
我有一个DataCollection
特定数据类(DataItem
)的集合类().集合实现接口IBindingList
,IList
,IList<DataItem>
和DataItem
工具INotifyPropertyChanged
(和具有公共属性的数据绑定).
当我尝试DataGridView
通过设置DataSource
网格的属性将集合绑定到a时,如果集合在绑定时不为空,则它可以正常工作.否则,如果集合为空,则在DataItems
从集合中添加或删除行(即)时,网格会注意到,但单元格保持为空.与此问题相关的是,网格无法识别数据类的公共成员, AutoGenerateColumns=true
并且无法生成列.
我也尝试过,DataItems
使用a 绑定BindingList<DataItem>
.在这种情况下,即使列表在设置时为空,网格也能正常工作DataSource
.另一方面,如果我使用BindingList<object>
(但DataItems
内容相同),行为与我的行为一样错误DataCollection
.我想问题是,如果在绑定时该列表为空,则数据绑定无法DataItem
正确检测到类型,并且当最终项目添加到集合时,它也无法在以后恢复.
重要的是,如果集合在绑定时不为空,则它可以工作.
请注意,我指定列时会发生相同的错误:
this.dataGridView.ReadOnly = true;
this.dataGridView.AutoGenerateColumns = false;
DataGridViewTextBoxColumn column;
column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "Id";
column.HeaderText = "Id";
this.dataGridView.Columns.Add(column);
column = new DataGridViewTextBoxColumn();
column.DataPropertyName = "UserName";
column.HeaderText = "UserName";
this.dataGridView.Columns.Add(column);
this.dataGridView.DataSource = myList; …
Run Code Online (Sandbox Code Playgroud)