多线程操作同一个文件,向文件写数据,能不能实现?
这个问题已经困扰我好久了,请各位高手帮忙,先谢谢大家了
我的线程是单独放在一个类里面,通过创建这个类的对象来创建线程,本来想用锁来控制线程,但是线程是在不同对象里的,所以没法控制,用lock,mutex,monitor都没用,但现在又遇到多线程写同一个文件这个问题,真是这个问题搞死了,
我的结构如下:
class A
{
..........
private void bt_select_Click(object sender, System.EventArgs e)
{
....
for(int i=0;i <xmllist.Count;i++)
{
B b=new B(xmllist[i],i);
}
....
}
..........
}
Class B
{
......
public B(string ip,string i)
{
Thread thd = new Thread(new ThreadStart(ExcuteImport));
j=i+1;
thd.Name= "线程 "+j+ ",支队ip: "+ip;
sb_log.Append( "/*******************************/ ");
sb_log.Append( "【 "+thd.Name+ "】 ");
thd.Start();
}
.......
private void writeFileLog()
{
DateTime dt=DateTime.Now;
FileStream fs;
string path=Directory.GetCurrentDirectory()+ "\\log\\ ";
string filename=dt.ToString( "d ")+ ".log ";
StreamWriter writeFileLog;
if(!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
fs=new FileStream(path+filename,FileMode.OpenOrCreate,FileAccess.Write,FileShare.ReadWrite);
writeFileLog=new StreamWriter(fs);
writeFileLog.Write(sb_log);
writeFileLog.Close();
fs.Close();
}
}
[解决办法]
可以啊 异步操作
[解决办法]
要用lock 在同一时刻只能有一个线程写该文件
[解决办法]
要确保同一时刻只能有一个线程操作该文件。。。。
[解决办法]
线程同步一定要小心呀
[解决办法]
lock吧...
不过我上个程序里面发现有lock锁不住的东西...........
[解决办法]
.NET Framework 类库
FileOptions 枚举
注意:此枚举在 .NET Framework 2.0 版中是新增的。
表示用于创建 FileStream 对象的附加选项。
成员名称 说明
Asynchronous 指示文件可用于异步读取和写入。
public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options);
[解决办法]
可以将所有写文件的操作交给一个线程来做,其他来调用并Lock
------解决方案--------------------
摘自msdn:
只要声明并创建一个对象作为锁,然后使用它而不是 类型对象来进行锁定。通常,为了复制问题代码的语义,您会希望此对象是 static/Shared — 当然,它其实应该是私有的!总之,您可以将以下问题代码:
// C#
lock(typeof(Foo)) { // BAD CODE! NO! NO! NO!
// statements;
}
' VB .NET
SyncLock GetType(MyClass) ' BAD CODE! NO! NO! NO!
' statements
End SyncLock
更改为以下正确代码:
// C#
lock(somePrivateStaticObject) { // Good code!
// statements;
}
' VB .NET
SyncLock GetType(somePrivateStaticObject) ' Good code!
' statements
End SyncLock
当然,您必须已经拥有一个要锁定的私有静态对象(如果您使用锁定来修改静态对象,实际上您可能已经有了一个!)或者必须创建一个。(使它成为私有对象可以避免其他类锁定您的对象。)请不要尝试锁定不是引用(对象)类型的字段,例如 int/Integer。那样会出现编译器错误。如果您没有要锁定的私有静态对象,可能需要创建一个哑对象:
// C#
Class MyClass {
private static Object somePrivateStaticObject = new Object();
// methods of class go here--can lock somePrivateStaticObject
}
' VB .NET
Class MyClass
Private Shared somePrivateStaticObject As New Object
' methods of class go here--can lock somePrivateStaticObject
End Class
您需要单独分析每种情况,以确保不会出现问题,但通常上述技巧会奏效。
有两点需要注意:首先,类以外的任何代码都无法锁定 MyClass.somePrivateStaticObject,因此避免了许多死锁的可能。由于死锁属于那种最难找到根源的问题,因此,避免发生死锁的可能是一件很好的事情。
其次,您知道,您的应用程序中只有一份 MyClass.somePrivateStaticObject 的副本,并且系统上运行的其他每个应用程序也只有一个副本。因此,在同一个应用程序域中的应用程序之间没有相互影响。GUI 博士希望您能明白为什么修改后的代码比原来的问题代码更加可靠和强大。
总之,不要锁定类型对象,因为您并不知道哪里又出现问题了。锁定类型对象的过程很慢,并且可能发生死锁情况。这是一种很不好的编程习惯。相反,您应该在对象中锁定静态对象。