代码想实现在不同的线程中读写文件,如果操作的是同一个文件,需要等待void FuncRead(string strFileName)
{
    lock (strFileName)
    {
        // read file
    }
}void FuncWrite(string strFileName)
{
    lock (strFileName)
    {
        // write file
    }
}
但这段代码是不工作的,因为 lock 锁得是对象,而不是字符串。在两个函数中strFileName虽然相等,但并不是同一个对象。请教怎么使用命名锁呢?就是通过制定的字符串内容来加锁解锁。

解决方案 »

  1.   

    Mutex mutex = new Mutex(false, "thename");
      

  2.   

    首先谢谢gomoku,查了下MSDN,这个方法应该是正确的。但我在开发WinPhone7程序,SilverLight中不支持Mutex,有没有其他变通的方法?
      

  3.   

    同一个进程里面 定义一个
    static string strFileName ="thename";
    就好了
      

  4.   

    可以在类中定义一个对象object _LockObj ,然后对它操作即可。
      

  5.   

    文件读写是可以共享的,
    看看WinPhone7下是否支持
      

  6.   

    这个是我曾经写过的一个方法
      private void BtnStart_Click(object sender, EventArgs e)
            {
                //锁定区域同时进行数据处理
                Monitor.Enter(threadlock);
                try
                {
                    //启动线程
                    ThreadStart thsrt = new ThreadStart(Listen);
                    //10个线程全部执行统一的方法
                    Thread[] threads = new Thread[10];                if (State)   //如果状态是true,表示可以开启
                    {
                        //循环10个线程
                        for (int i = 0; i < 10; i++)
                        {
                            threads[i] = new Thread(thsrt);
                            //设置线程为后台后台线程 ,也叫守护线程
                            threads[i].IsBackground = true;
                        }
                        //循环遍历所有的10个线程
                        foreach (Thread th in threads)
                        {
                            //开启线程
                            th.Start();
                        }
                        //将状态改为false
                        State = false;
                        this.Messagetxt.Text = "服务已启动,正在侦听...";
                    }
                    else
                    { 
                        //中断线程
                        mythread.Interrupt();
                        //终止线程
                        mythread.Abort();
                        State = true;
                        this.Messagetxt.Text = "服务已关闭,等待开启...";
                    }
                }
                catch (Exception ex)
                {
                    DAL.Log.Write(DateTime.Now + ex.ToString() + "\r\n");
                }
                finally
                {
                    //退出对于线程的锁定
                    Monitor.Exit(threadlock);
                }
            }我觉得你应该有用
      

  7.   

    To 5楼6楼的兄弟:
    strFileName是运行中得到的值,因此无法用对象来加锁(理论上也可以,只是太麻烦了)
    To 7楼的兄弟:
    支持共享读写,但我在这里希望写完了再读。理论上可以禁止共享的方式写,这样读的时候就会出异常,然后重试。但是操作比较繁琐,而且等待时间及次数不好控制。可以作为备选方案
    To 8楼得兄弟:
    这个貌似是对象锁。不管怎么说还是谢了
      

  8.   

    目前看来,C#中能使用的命名锁只有mutex了?
      

  9.   

    貌似FuncRead和FuncWrite可能在不同线程中操作同一个字符串,如果这两个方法都由你控制,一个笨办法就是在方法内都使用一个可以加锁的对象,对象中包含一个保存字符串的静态数组,初始化时使用工厂模式,构造时传入字符串,如果字符串存在则直接取它,肯定时可以,就是比较绕。
      

  10.   

    class ObjForLock
    {
      List< ObjForLock> =new List<ObjForLock>(); //也可以用dictionary
      
      string _Str;
      
      private ObjForLock(string str)
      {
        _Str=str;
      }
      public Static ObjForLock FactoryOFL(string lkstr)
       {
         ObjForLock rst= FindStr(lkstr)
           if(rst==null)
             return new ObjForLock(lkstr);
       }
       private static ObjForLock FindStr(string str)
       {
         .....
       }
     }
      

  11.   

    你的问题可以采用异步读写方式:
    先异步写文件,异步操作都有一个完成事件,当完成后你在读即可。参考
    //
            // 摘要:
            //     开始异步写。
            //
            // 参数:
            //   offset:
            //     array 中的从零开始的字节偏移量,从此处开始将字节复制到当前流。
            //
            //   array:
            //     包含要写入当前流的数据的缓冲区。
            //
            //   numBytes:
            //     最多写入的字节数。
            //
            //   userCallback:
            //     异步写操作完成后调用的方法。
            //
            //   stateObject:
            //     一个用户提供的对象,它将该特定的异步写入请求与其他请求区别开来。
            //
            // 返回结果:
            //     引用异步写的 System.IAsyncResult。
            public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject);
      

  12.   

    。net 线程命名空间中有很多可以线程同步资源的类,自己看看
      

  13.   

    to 11 12楼的兄弟 及 14楼的兄弟:
    其实想到这种方法了
    指的就是这种方式。
    实际上访问那个List or dictionary也是需要加锁的,会麻烦不少。当然封装一下,也是一种不错的解决方法。另外我在尝试找c#语言本身支持的内置方法,这不算偷懒吧。毕竟一般情况下,内置方法稳定性、效率、通用性都不错。
    to 13楼:
    这是个不错的思路,研究一下。这段代码是为了下载网络图片,并缓存到本地的。如果请求的图片已经存在,就不用下载,直接读本地文件了。
    另外为了防止连续发起多次同一图片的下载请求,将处理中的请求保存在一个dictionary中了(访问这个dictionary需要加锁。发起请求是加入,处理完成即图片保存完毕移除)。
    所以最终解决方法为先判断一个url请求是否在列表中,在判断是否在本地,最后才去下载。
    谢谢的大家帮助。
      

  14.   

    一般这样
    private static object m_objLock1 = new object();