项目中有块实时监控的内容,大概意思是一个线程负责把符合条件的值保存到Hashtable中,另一个线程不断的从这个Hashtable中读取数据,在这个过程中俩个线程同时操作Hashtable会报错误,从网上找了好多资料都没有解决,请各位高手帮忙!
下面是运行时会错的代码,请各位高手在次代码上进行修改:
using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
}
public void HsAdd()
{
while (true)
{
hs.Add(index, DateTime.Now.ToString());
index++;
Thread.Sleep(1000);
}
}
public void HsWrite()
{
while (true)
{
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
Thread.Sleep(1000);
}
}
}
}
}
下面是运行时会错的代码,请各位高手在次代码上进行修改:
using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
}
public void HsAdd()
{
while (true)
{
hs.Add(index, DateTime.Now.ToString());
index++;
Thread.Sleep(1000);
}
}
public void HsWrite()
{
while (true)
{
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
Thread.Sleep(1000);
}
}
}
}
}
解决方案 »
- ContextMenuStrip如何动态加入菜单项并关联click事件
- 关于gridview 大侠进 在线等
- 这样的DataGridView如何实现?(分不够的话再加)
- 关于弹出窗口最小化问题
- Error: creating window handle
- 访问页面时判断是否是登陆用户,关于session的问题
- 如何把Form运行起来的时候自动位于屏幕中间?
- 那位高手有反向依赖的例子?
- 怎么样才可以得到数据的行数,并赋值到一个参数!跪谢!急!
- 请教如何输出资源文件中的图片对象
- 欢迎了解我们的一个开源项目:SmartTank人工智能游戏平台。
- 用Serialport进行串口通讯,如何发byte,int等类型的命令或数据
lock (hs) {
while (true) {
hs.Add(index, DateTime.Now.ToString());
index++;
Thread.Sleep(1000);
}
}
}
按照你的样子加入了lock,但在HsWrite里读取时还是报错误。to:lovefootball
在什么地方使用lock?
public void HsWrite()
{
lock (hs) {
while (true)
{
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
Thread.Sleep(1000);
}
}
}
}
这样会导致部分数据加不到Hashtable里,还有其他的办法吗?
这个方法试过了,偶尔也会报错误
这个方法试过了,偶尔也会报错误
====
能保证只有一个线程在写吗?
using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
}
public void HsAdd()
{
while (true)
{
lock (hs)
{
hs.Add(index, DateTime.Now.ToString());
}
index++;
Thread.Sleep(1000);
}
}
public void HsWrite()
{
while (true)
{
lock (hs)
{
IDictionaryEnumerator ie = hs.GetEnumerator();
ie.MoveNext();
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
}
Thread.Sleep(1000);
}
}
}
}
using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
Thread thHsDel = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
thHsDel = new Thread(new ThreadStart(this.HsDel));
thHsDel.Start();
}
public void HsAdd()
{ while (true)
{
lock (hs.SyncRoot)
{
hs.Add(index, DateTime.Now.ToString());
}
index++;
Thread.Sleep(10);
}
}
public void HsWrite()
{
Hashtable tp = null;
while (true)
{
tp = (Hashtable)hs.Clone();
IDictionaryEnumerator ie = tp.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
Thread.Sleep(100);
}
}
}
public void HsDel()
{
Hashtable tp = null;
while (true)
{
tp = (Hashtable)hs.Clone();
IDictionaryEnumerator ie = tp.GetEnumerator();
while (ie.MoveNext())
{
if (ie.Key.ToString().IndexOf("0") > -1)
{
lock (hs.SyncRoot)
{
hs.Remove(ie.Key);
}
Console.WriteLine("--------------------------------已删除对象{0}------------------------------" ,ie.Key);
}
Thread.Sleep(10); //必须加,有效降低CPU占有率
}
}
}
}
}
给你改了一下程序using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
Hashtable hs;
Hashtable hsSync;
public test()
{
hs = new Hashtable();
hsSync = Hashtable.Synchronized(hs);
}
Thread thHsAdd = null;
Thread thHsWrite = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
}
public void HsAdd()
{
while (true)
{
lock (hsSync)
{
hsSync.Add(index, DateTime.Now.ToString());
index++;
Thread.Sleep(1000);
}
}
}
public void HsWrite()
{
while (true)
{
int nCount = hsSync.Keys.Count;
for (int i = 0; i < nCount; i++)
{
Console.WriteLine( i.ToString() + hsSync[i].ToString());
}
Console.WriteLine("------------------------------------");
}
}
}
}
{
Hashtable tp = null;
while (true)
{
tp = (Hashtable)hs.Clone();
IDictionaryEnumerator ie = tp.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
Thread.Sleep(100);
}
}
}
注意检查一下这段代码,可能使你的程序: 每次读hashtable时间间隔越来越长(100*hashtable成员个数 ms),这样写的程序结果是很奇怪和不可控的。
using System;
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
test t = new test();
t.Start();
}
}
public class test
{
System.Threading.ManualResetEvent obj = new ManualResetEvent(false);
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
}
public void HsAdd()
{ while (true)
{
if (obj.WaitOne(10, false) == true)
{
hs.Add(index, DateTime.Now.ToString());
index++;
}
Thread.Sleep(1000);
}
}
public void HsWrite()
{
while (true)
{
obj.Reset();
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
}
obj.Set();
Thread.Sleep(1000);
}
}
}
}
using System.Collections;
using System.Threading;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{
class Program1
{
static void Main(string[] args)
{
test1 t = new test1();
t.Start();
}
} public class test1
{
System.Threading.ManualResetEvent obj = new ManualResetEvent(false);
Hashtable hs = new Hashtable();
Thread thHsAdd = null;
Thread thHsWrite = null;
Thread thHsDel = null;
int index = 0;
public void Start()
{
thHsAdd = new Thread(new ThreadStart(this.HsAdd));
thHsAdd.Start();
thHsWrite = new Thread(new ThreadStart(this.HsWrite));
thHsWrite.Start();
thHsDel = new Thread(new ThreadStart(this.HsDel));
thHsDel.Start();
}
public void HsAdd()
{ while (true)
{
if (obj.WaitOne(10,false) == true)
{
hs.Add(index, DateTime.Now.ToString());
index++;
}
Thread.Sleep(10);
}
}
public void HsWrite()
{
while (true)
{
obj.Reset();
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
Console.WriteLine("key={0},value={1}", ie.Key, ie.Value);
}
obj.Set();
Thread.Sleep(10);
}
}
public void HsDel()
{
while (true)
{
obj.Reset();
IDictionaryEnumerator ie = hs.GetEnumerator();
while (ie.MoveNext())
{
if (ie.Key.ToString().IndexOf("0") > -1)
{
//lock (hs)
//{
// hs.Remove(ie.Key);
//}
Console.WriteLine("--------------------------------已删除对象{0}------------------------------", ie.Key);
}
}
obj.Set();
Thread.Sleep(10);
}
}
}
}