Это может быть совершенно неправильно, но я понимаю, что это смесь отложенного перечисления с WhereArrayIterator
, и отладчик пытается его перечислить?
У меня такое ощущение, что непосредственное окно пытается перечислить ваш результат, оно делает это в другом потоке (что вызывает CrossThreadMessagingException
).
Этого не происходит, когда вы вызываете ToList
, потому что ToList
вызывает немедленное выполнение перечисления и объединение результатов в списке. Это делается до того, как вы попытаетесь использовать метод Count
в непосредственном окне.
Когда вы используете Count()
без вызова ToList
, он заставляет WhereArrayIterator
(которое является возвращаемым значением вашего вызова метода Where
) перечислять, что затем пытается получить доступ к вашему лямда-делегату из другого потока.
При тестировании вы можете фактически перечислить другие экземпляры WhereArrayIterator
через немедленный, поэтому я думаю, что это ваш конкретный вариант использования, когда вы пытаетесь перечислить тип Process
, который, как я думаю, выполняет внутренние вызовы с использованием Win32 API.
Внутренне свойство Process.MainWindowTitle
использует ленивую загрузку для своего значения. На самом деле он не выполняет вызов для получения информации до тех пор, пока к свойству не будет получен доступ в первый раз (и также он делает это без блокировки, поэтому, если несколько потоков обращаются к этой области кода, это не атомарный, поэтому существует риск наследования условий гонки - в любом случае это не должно иметь большого значения, так как это свойство доступно только для чтения, чье значение всегда должно быть одним и тем же).
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[MonitoringDescription("ProcessMainWindowTitle")]
public string MainWindowTitle
{
get
{
if (this.mainWindowTitle == null)
{
IntPtr mainWindowHandle = this.MainWindowHandle;
if (mainWindowHandle == (IntPtr) 0)
{
this.mainWindowTitle = string.Empty;
}
else
{
StringBuilder lpString = new StringBuilder(Microsoft.Win32.NativeMethods.GetWindowTextLength(new HandleRef((object) this, mainWindowHandle)) * 2);
Microsoft.Win32.NativeMethods.GetWindowText(new HandleRef((object) this, mainWindowHandle), lpString, lpString.Capacity);
this.mainWindowTitle = ((object) lpString).ToString();
}
}
return this.mainWindowTitle;
}
}
При первом доступе к свойству выполняется вызов Win32 для захвата текста окна. Я считаю, что это то место, где он, кажется, падает. Но кажется, что это происходит только при использовании отложенного перечисления с вашим экземпляром WhereArrayIterator
.
Это все слепые догадки, если честно!
person
Matthew Abbott
schedule
01.09.2011