Reputation: 9286
Is it possible to instantiate a class in a separate thread without a compile time warning?
For example the below code gives the compile time error "Use of unassigned local variable BECheck". I would rather keep AvailabilityCheckBase abstract and not assign it some dummy variable. Creating both BTCheck and BECheck is slow which is why I need it threaded.
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);
}
Upvotes: 0
Views: 743
Reputation: 43064
If you assign the values to null
you should see the message disappear, this would be good practice. There also doesn't appear to be any checking to make sure that the initialisations worked, you should probably include a check for BECheck and BTCheck still being null at the end of the function before you try to return to avoid an exception being thrown.
Upvotes: 1
Reputation: 9912
In order to call BECheck.Merge
in your last line, BECheck
should be initialized, and the compiler doesn't know it will be created before Thread.Join
.
Try writing
AvailabilityCheckBase BECheck = null;
AvailabilityCheckBase BTCheck = null;
in the first lines.
Upvotes: 2
Reputation: 1499790
The language has no knowledge of the Thread
constructor or the Join
method: it can't tell that you will definitely assign values to both variables before Join
returns. If you want to keep the current approach, you'll need to assign values to the variables first. I agree this is slightly ugly, but it's the only way of keeping the compiler happy here.
(It's not clear why you're creating two new threads here, given that your original thread is then blocking on both of them, by the way.)
A better approach if you're using .NET 4 would be to use Task<T>
, which effectively gives you the "promise" of a value:
Task<AvailabilityCheckBase> beCheck =
Task.Factory.StartNew(() => new BEAvailabilityCheck(dsl));
Task<AvailabilityCheckBase> btCheck =
Task.Factory.StartNew(() => new BTAvailabilityCheck(dsl));
return beCheck.Result.Merge(btCheck.Result);
It's worth becoming familiar with Task<T>
and the TPL in general, as the new async features in C# 5 are heavily dependent on them.
Upvotes: 4
Reputation: 6293
Use Task's:
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;
Upvotes: 0
Reputation: 63340
Doesn't this fix your compile error? :
change
AvailabilityCheckBase BECheck;
AvailabilityCheckBase BTCheck;
to
AvailabilityCheckBase BECheck = null;
AvailabilityCheckBase BTCheck = null;
Upvotes: 3