您的位置:程序门 -> .net技术 -> c#



多线程操作同一个文件,向文件写数据,能不能实现?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


多线程操作同一个文件,向文件写数据,能不能实现?[已结贴,结贴人:reborter]
发表于:2007-02-08 15:50:32 楼主
这个问题已经困扰我好久了,请各位高手帮忙,先谢谢大家了
我的线程是单独放在一个类里面,通过创建这个类的对象来创建线程,本来想用锁来控制线程,但是线程是在不同对象里的,所以没法控制,用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();
      }
}
发表于:2007-02-08 15:53:571楼 得分:3
可以啊     异步操作
发表于:2007-02-08 15:59:162楼 得分:3
要用lock   在同一时刻只能有一个线程写该文件
发表于:2007-02-08 16:01:373楼 得分:3
要确保同一时刻只能有一个线程操作该文件。。。。
发表于:2007-02-08 16:01:564楼 得分:3
线程同步一定要小心呀
发表于:2007-02-08 16:08:215楼 得分:3
lock吧...
不过我上个程序里面发现有lock锁不住的东西...........
发表于:2007-02-08 16:48:396楼 得分:0
我用了lock(this),mutex,monitor都没用啊,怎么没回事
发表于:2007-02-08 16:57:097楼 得分:0
我想声明的是:
创建线程是单独放在b类里,通过a类循环创建b类的对象来创建线程的,可能楼上的几位没明白我的意思,现在问题就是我想通过锁来控制线程,但是现在不行,控制不了,还有大家看看我写的writefilelog函数有没有问题
发表于:2007-02-08 16:58:078楼 得分:0
呵呵,忘了谢楼上几位了,请教各位高手,不知道我说的意思有没有说清楚
发表于:2007-02-09 16:30:009楼 得分:5
.net   framework   类库    
fileoptions   枚举    
注意:此枚举在   .net   framework   2.0   版中是新增的。  

表示用于创建   filestream   对象的附加选项。  

    成员名称   说明  
    asynchronous   指示文件可用于异步读取和写入。      

  public   filestream(string   path,   filemode   mode,   fileaccess   access,   fileshare   share,   int   buffersize,   fileoptions   options);

发表于:2007-02-09 16:48:5510楼 得分:0
我的是.net1.1的,用lock,不知道锁定哪个对象,都锁不了
发表于:2007-02-09 17:04:3111楼 得分:0
lock()
发表于:2007-02-09 17:13:3812楼 得分:0
在线朋友帮帮忙啊,多线程怎么来控制,我想让它一个线程执行完了之后再执下一个线程,现在就是lock不了.还请各位多多帮忙!
顶者有分
发表于:2007-02-09 17:22:3513楼 得分:0
lock是一个关键字,在.net2003有
发表于:2007-02-09 17:23:2314楼 得分:5
可以将所有写文件的操作交给一个线程来做,其他来调用并lock
发表于:2007-02-09 17:34:2815楼 得分:0
to   liangxf0022(小新):
我知道lock有,不知道你有没有看我的问题
我这个程序功能是从10多个支服务器取数据,所以要把取数据的情况写在日志文件当中。
象你说的实现方法,我比较愚昧,还请小新您多指教..

假如我现在就是想怎么来锁定线程,让它一个线程执行完,接着执行下一个线程,该怎么做?
刚才我在发的另一帖里,feiyun0112(http://feiyun0112.cnblogs.com/)这位朋友,写的下列代码,
private   static   object   lockobj   =null;

lock(lockobj)
{
writefilelog
}

还是不怎么明白,各位看得懂的话,能不能解释一下
发表于:2007-02-09 18:03:4516楼 得分:0
写文件的代码做为公用的,放在一个类里。lock表示同一时间只会有一个线程执行被lock的代码块,这个可以控制多线程写文件。如果是要一个线程在另一线程执行完之后才会执行,可以用信号量控制。
发表于:2007-02-09 18:29:3017楼 得分:0
谢谢scow(怡红快绿之小橙子),但我不是问lock的作用,我是指刚才private   static   object   lockobj=null这个怎么锁定,这个静态变量不是很明白.
刚才你说的用信号量控制应该怎么做,怎么个实现原理?
发表于:2007-02-09 18:34:1818楼 得分:0
我不知道是不是我说的问题不清楚,还是怎么回事.

我现在的问题就是我用lock不能锁定线程,而且目的就是要一个线程在另一线程执行完之后才会执行
发表于:2007-02-09 19:19:5219楼 得分:0
1.锁定类型对象可能造成死锁,现在比较通用的做法是锁定一个静态对象,因为静态对象在同一个app   domain只有一份,所以锁定它可以保证代码不会被多线程同时执行。
2.manualresetevent   or   autorestevent,详细说明可参考msdn
发表于:2007-02-09 21:17:2120楼 得分:0
你说的appdomain是不是临介区呢?
还是刚才这段代码
private   static   object   lockobj   =null;

lock(lockobj)
{
writefilelog
}
它这个怎么执行原理,
发表于:2007-02-10 07:51:3221楼 得分:0
up
发表于:2007-02-10 09:03:2222楼 得分:25
摘自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   博士希望您能明白为什么修改后的代码比原来的问题代码更加可靠和强大。
总之,不要锁定类型对象,因为您并不知道哪里又出现问题了。锁定类型对象的过程很慢,并且可能发生死锁情况。这是一种很不好的编程习惯。相反,您应该在对象中锁定静态对象。


快速检索

最新资讯
热门点击