我是线程新手,我想知道如何使用它们在非确定性有限自动机中进行评估。
我有调用另一个方法的方法:
public bool Evaluate2(string s)
{
accepted = false;
ThreadEval(s, StartState);
return accepted;
}
变量accepted
是一个类成员,我用它来控制其他线程何时停止。
void ThreadEval(string s, State q)
{
if (s.Length == 0 && q.IsFinal)
{
accepted = true;
return;
}
bool found = true;
State current = q;
for (int i = 0; found && !accepted && i < s.Length; i++)
{
found = false;
foreach (Transition t in current.transitions)
if (t.symbol == s[i])
{
Thread thread = new Thread(new ThreadStart(delegate { ThreadEval(s.Substring(i+1), t.to); }));
thread.Start();
found = true;
}
}
}
我的每个状态都有一组转换。转换由符号和通过使用该符号可以进入的状态组成。因此,每当找到可能的转换时,我都想创建一个新线程并检查字符串的其余部分(没有当前字符)...
我目前有2个问题:
在 ThreadEval 中创建的所有线程完成它们之前,正在执行“接受的返回”。有没有办法确保在这些线程完成之前它不会返回?我在返回之前放了一个 Thread.Sleep(200) 并且它有效,但是对于大字符串来说 200 毫秒可能还不够,我也不想提高这个值,所以小字符串需要比它们应该处理的时间更长的时间.
代码导致某些索引异常的方式......我 99.999% 确信它是正确的,但如果我调用 Substring 传递值i而不是i + 1 ,它只会停止崩溃。 ..但如果我只用i调用它就永远不会到达字符串的末尾,并且取决于自动机配置可能会导致无限循环。我不确切知道线程是如何工作的,但我怀疑某些并行处理可能会在子字符串切片之前改变i的值。我如何确保每当我调用一个新线程时,我只会丢弃当前的字符?
如果有人对如何更优雅地使用线程有任何建议,我将不胜感激,到目前为止,我发现在分配线程的函数中传递参数的唯一方法是使用委托。