我有一个构造函数,它在名为Regex
的类中使用static readonly
个RegexLib
个对象(主要是因为这个项目使用了大量需要的Regex
个模式在各处使用。
当用户向应用程序添加一些文件时,将为每个文件调用此构造函数一次(跨多个线程异步运行)。我已经附加了构造函数在下面调用的相关函数。
private void GetSymbolsFromLines()
{
for (int i = 0; i < Lines.Length; i++)
{
string line = Lines[i];
if (RegexLib.InstString.IsMatch(line))
{
int instString = i;
int userdataString = 0;
for (int j = i; j < Lines.Length; j++)
{
if (RegexLib.UserdataString.IsMatch(Lines[j]))
{
userdataString = j;
break;
}
else if (Lines[j].Contains("userdata"))
{
break;
}
}
if (userdataString != 0)
{
_symbols.Add(new Symbol(RegexLib.InstString.Match(Lines[instString]),
RegexLib.UserdataString.Match(Lines[userdataString])));
}
}
}
}
Regex
个对象与这些对象非常相似,并且已使用Regex Hero进行了测试。
public static readonly Regex AliasFromUserdata = new Regex(@"text_alias=(?<AliasName>\w+).*?value=(?<AliasValue>(.*?))\^(?=(?:text_alias|\""))");
public static readonly Regex UpdateFromUserdata = new Regex("FOX_VAR=.*?attr=(?<AttributeType>.+?)\\^(?<AttributePropertyString>.*?)\\^(?:(?=(?:FOX_VAR|END_FOXV)))");
出于某种原因,Regex
的使用似乎在这个多线程环境中引起了一些问题,并且挖掘documentation显示这可能是因为:
但是,Regex返回的结果对象(Match和MatchCollection)应该在一个线程上使用。
所以我的问题是,出于组织原因,是否有一种简单的方法可以使用Regex
跨越多个线程,同时在库类中构建它们?
我能想到的唯一可能的解决方案是将Regex
声明移近使用是在使用前克隆对象,但这看起来可能很慢。
作为参考,这里是在4个不同线程上并发运行的Worker Function。
private void FoxFileConvWorker(ConcurrentQueue<string> queue,QueueProgressData qpd)
{
string[] extensions = {".fdf", ".m1", ".g"};
while (!queue.IsEmpty)
{
string file;
if (queue.TryDequeue(out file))
{
if (extensions.Any(extension => Path.GetExtension(file) == extension))
{
try
{
_jobGraphics.Add(new Graphic(file));
IncrementProgress(qpd);
}
catch (Exception e)
{
ThreadSafeControlMethods.SetText(qpd.LblStatus, "Non-Fatal Error");
WriteLog(e, $"Creating Graphic DOM for {file}");
#if DEBUG
throw;
#endif
}
}
}
}
}
答案 0 :(得分:2)
您可以修改静态Regex类吗?如果是这样,您可以使用Factory而不是静态属性:
default-time-zone = YourTimezone
这样,你就不会在线程之间共享你的正则表达式了。
您也可以使用一些依赖注入,但这意味着您的代码中会进行大量的重构。