代码想实现在不同的线程中读写文件,如果操作的是同一个文件,需要等待void FuncRead(string strFileName)
{
lock (strFileName)
{
// read file
}
}void FuncWrite(string strFileName)
{
lock (strFileName)
{
// write file
}
}
但这段代码是不工作的,因为 lock 锁得是对象,而不是字符串。在两个函数中strFileName虽然相等,但并不是同一个对象。请教怎么使用命名锁呢?就是通过制定的字符串内容来加锁解锁。
{
lock (strFileName)
{
// read file
}
}void FuncWrite(string strFileName)
{
lock (strFileName)
{
// write file
}
}
但这段代码是不工作的,因为 lock 锁得是对象,而不是字符串。在两个函数中strFileName虽然相等,但并不是同一个对象。请教怎么使用命名锁呢?就是通过制定的字符串内容来加锁解锁。
static string strFileName ="thename";
就好了
看看WinPhone7下是否支持
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);
}
}我觉得你应该有用
strFileName是运行中得到的值,因此无法用对象来加锁(理论上也可以,只是太麻烦了)
To 7楼的兄弟:
支持共享读写,但我在这里希望写完了再读。理论上可以禁止共享的方式写,这样读的时候就会出异常,然后重试。但是操作比较繁琐,而且等待时间及次数不好控制。可以作为备选方案
To 8楼得兄弟:
这个貌似是对象锁。不管怎么说还是谢了
{
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)
{
.....
}
}
先异步写文件,异步操作都有一个完成事件,当完成后你在读即可。参考
//
// 摘要:
// 开始异步写。
//
// 参数:
// offset:
// array 中的从零开始的字节偏移量,从此处开始将字节复制到当前流。
//
// array:
// 包含要写入当前流的数据的缓冲区。
//
// numBytes:
// 最多写入的字节数。
//
// userCallback:
// 异步写操作完成后调用的方法。
//
// stateObject:
// 一个用户提供的对象,它将该特定的异步写入请求与其他请求区别开来。
//
// 返回结果:
// 引用异步写的 System.IAsyncResult。
public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, object stateObject);
其实想到这种方法了
指的就是这种方式。
实际上访问那个List or dictionary也是需要加锁的,会麻烦不少。当然封装一下,也是一种不错的解决方法。另外我在尝试找c#语言本身支持的内置方法,这不算偷懒吧。毕竟一般情况下,内置方法稳定性、效率、通用性都不错。
to 13楼:
这是个不错的思路,研究一下。这段代码是为了下载网络图片,并缓存到本地的。如果请求的图片已经存在,就不用下载,直接读本地文件了。
另外为了防止连续发起多次同一图片的下载请求,将处理中的请求保存在一个dictionary中了(访问这个dictionary需要加锁。发起请求是加入,处理完成即图片保存完毕移除)。
所以最终解决方法为先判断一个url请求是否在列表中,在判断是否在本地,最后才去下载。
谢谢的大家帮助。
private static object m_objLock1 = new object();