C# 队列的InvalidCastException<;字符串>;在多线程应用程序中
输出缓冲区声明为类变量C# 队列的InvalidCastException<;字符串>;在多线程应用程序中,c#,string,exception,.net,C#,String,Exception,.net,输出缓冲区声明为类变量 private Queue<String> __OutputBuffer = new Queue<String>(); private void ProcessOutput() { if (__OutputBuffer.Count > 0 && !String.IsNullOrEmpty(__OutputBuffer.Peek())) { object _Item = __OutputBuff
private Queue<String> __OutputBuffer = new Queue<String>();
private void ProcessOutput()
{
if (__OutputBuffer.Count > 0 && !String.IsNullOrEmpty(__OutputBuffer.Peek()))
{
object _Item = __OutputBuffer.Dequeue();
if(_Item is String)
{
try
{
Browser.DocumentText += "<span style='font-family: Tahoma; font-size: 9pt;'>" + _Item + "</span>";
//Exception On Line Above!
}
catch (Exception) { }
}
}
}
处理队列
private Queue<String> __OutputBuffer = new Queue<String>();
private void ProcessOutput()
{
if (__OutputBuffer.Count > 0 && !String.IsNullOrEmpty(__OutputBuffer.Peek()))
{
object _Item = __OutputBuffer.Dequeue();
if(_Item is String)
{
try
{
Browser.DocumentText += "<span style='font-family: Tahoma; font-size: 9pt;'>" + _Item + "</span>";
//Exception On Line Above!
}
catch (Exception) { }
}
}
}
我得到了无效的强制转换异常,下面是获取异常时_项的内容
**此外,以下情况会导致异常。。。所以我怀疑这是队列中字符串的内容
队列
不是线程安全的,而System.Timers.Timer
在随机池线程上触发其事件。这是调用ProcessOutput
的地方,也是调用\u OutputBuffer.Dequeue()
和访问Browser.DocumentText
的地方
您可以使用
锁保护\u OutputBuffer
不受并发访问(对于出列
和入列
),或者改用并发队列
。但是,您需要将浏览器.DocumentText
分配封送到UI线程,例如使用控件.Invoke
或控件.BeginInvoke
正如Noserio所说,队列
不是线程安全的,但是,如果您不希望在项目中使用锁定,并且正在使用.NET 4.0或更新版本,则可以使用线程安全的类
您需要进行一些更改,例如没有Peek
或Dequeue
方法,而必须使用TryPeek
和TryDequeue
。但是它不需要太多的主要更改,它甚至可以让您进行一些优化,因为如果队列为空,这两个try方法将返回false
,因此您不再需要计数
检查
private void ProcessOutput()
{
string output;
if (__OutputBuffer.TryDequeue(out output) && !String.IsNullOrEmpty(output))
{
try
{
Browser.DocumentText += "<span style='font-family: Tahoma; font-size: 9pt;'>" + output + "</span>";
}
catch (Exception) { } // <--- Blindly catching exceptsions is almost never the right thing to do.
}
}
private void ProcessOutput()
{
字符串输出;
if(uuu OutputBuffer.TryDequeue(输出)&!String.IsNullOrEmpty(输出))
{
尝试
{
Browser.DocumentText+=“”+输出+“”;
}
使用计时器捕获(异常){}/被认为是多线程的。
您每100毫秒有一个新线程,这可能会导致您在退出队列时遇到竞争条件
使用:
private ConcurrentQueue\uuu OutputBuffer=new ConcurrentQueue();
私有void ProcessOutput()
{
字符串_项;
if(uu OutputBuffer.TryDequeue(out项目))
{
尝试
{
Browser.DocumentText+=“”+\u Item+“”;
//上面一行出现异常!
}
捕获(异常){}
}
}
队列
不是线程安全的,并且系统.计时器.Timer
在随机池线程上触发其事件,这就是调用ProcessOutput
的地方,也是访问浏览器.DocumentText
的地方。我已经解决了这个问题。我在浏览器上使用了.Invoke。不确定我的解决方案是否很好,请告知。为什么您是否Peek
然后Dequeue
?,如果您的队列中有空字符串,您将停止处理,因为它将永远不会退出队列。祝贺10K代表,感谢您的回答:)
private ConcurrentQueue<String> __OutputBuffer = new ConcurrentQueue<String>();
private void ProcessOutput()
{
string _Item;
if (__OutputBuffer.TryDequeue(out _Item))
{
try
{
Browser.DocumentText += "<span style='font-family: Tahoma; font-size: 9pt;'>" + _Item + "</span>";
//Exception On Line Above!
}
catch (Exception) { }
}
}