在没有编译时警告的情况下,在单独的线程中实例化类
本文关键字:线程 单独 实例化 情况下 编译 警告 | 更新日期: 2023-09-27 18:25:28
是否可以在没有编译时警告的情况下在单独的线程中实例化类?
例如,下面的代码给出了编译时错误"使用未分配的局部变量BECheck"。我宁愿保持AvailabilityCheckBase的抽象,而不是给它分配一些伪变量。创建BTCheck和BECheck都很慢,这就是我需要线程化的原因。
public static AvailabilityCheckBase ByDSL(string dsl)
{
AvailabilityCheckBase BECheck;
AvailabilityCheckBase BTCheck;
Thread BEThread = new Thread(new ThreadStart(() => BECheck = new BEAvailabilityCheck(dsl)));
Thread BTThread = new Thread(new ThreadStart(() => BTCheck = new BTAvailabilityCheck(dsl)));
BEThread.Join();
BTThread.Join();
return BECheck.Merge(BTCheck);
}
该语言对Thread
构造函数或Join
方法一无所知:在Join
返回之前,它无法判断您肯定会为这两个变量赋值。如果您想保持当前的方法,您需要首先为变量赋值。我同意这有点难看,但这是让编译器满意的唯一方法。
(顺便说一句,考虑到你的原始线程在这两个线程上都被阻塞,你为什么要在这里创建两个新线程还不清楚。)
如果您使用.NET4,一个更好的方法是使用Task<T>
,它有效地为您提供了一个值的"承诺":
Task<AvailabilityCheckBase> beCheck =
Task.Factory.StartNew(() => new BEAvailabilityCheck(dsl));
Task<AvailabilityCheckBase> btCheck =
Task.Factory.StartNew(() => new BTAvailabilityCheck(dsl));
return beCheck.Result.Merge(btCheck.Result);
一般来说,熟悉Task<T>
和TPL是值得的,因为C#5中新的异步特性在很大程度上依赖于它们。
这难道不能修复编译错误吗?:
更改
AvailabilityCheckBase BECheck;
AvailabilityCheckBase BTCheck;
至
AvailabilityCheckBase BECheck = null;
AvailabilityCheckBase BTCheck = null;
为了在最后一行中调用BECheck.Merge
,应该初始化BECheck
,而编译器不知道它将在Thread.Join
之前创建。
尝试写入
AvailabilityCheckBase BECheck = null;
AvailabilityCheckBase BTCheck = null;
在第一行中。
如果您将值分配给null
,您应该会看到消息消失,这将是一个很好的做法。似乎也没有任何检查来确保初始化有效,您可能应该在函数末尾检查BECheck和BTCheck是否仍然为null,然后再尝试返回以避免引发异常。
使用任务:
Task<AvailabilityCheckBase> BETask = new Task<AvailabilityCheckBase>(() => BECheck = new BEAvailabilityCheck(dsl));
Task<AvailabilityCheckBase> BTTask = new Task<AvailabilityCheckBase>(() => BECheck = new BTAvailabilityCheck(dsl));
BETask.WaitAll(BETask,BTTask);
AvailabilityCheckBase BECheck = BETask.Result;
AvailabilityCheckBase BTCheck = BTTask.Result;