Недопустимый межпоточный доступ в WP7 после заполнения ObservableCollection в потоке, отличном от пользовательского интерфейса.

Я борюсь с операциями с перекрестными потоками в WP7. Элементы успешно добавляются в ObservableCollection, но затем ничего не отображается. Связанный с данными ListBox (lBox) дает:

Недопустимый межпоточный доступ.

Вот что у меня есть:

public partial class MainPage : PhoneApplicationPage
{
    private ObservableCollection<string> obrazkiFinal = new ObservableCollection<string>();

    public ObservableCollection<string> ObrazkiFinal
    {
        get { return obrazkiFinal; }
        set { obrazkiFinal = value; }
    }

    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        lBox.ItemsSource = ObrazkiFinal;

        HttpWebRequest httpRequest = WebRequest.CreateHttp(@"http://website");
        IAsyncResult res = httpRequest.BeginGetResponse(new AsyncCallback(RespResult),httpRequest);
    }

    private void RespResult(IAsyncResult respResylt)
    {
        var res = (HttpWebRequest)respResylt.AsyncState;
        var resp = res.EndGetResponse(respResylt);

        /* some parsing code */
         foreach (/* found pic urls */)
         {
             //new httpwebrequest
             HttpWebRequest picHttpRequest = WebRequest.CreateHttp(picUrl);
             IAsyncResult picRes = picHttpRequest.BeginGetResponse(DownloadImageResult, picHttpRequest );

       }

    private void DownloadImageResult(IAsyncResult result)
    {
        var res = state.HttpWebRequest;
        var resp = res.EndGetResponse(result);

        /*some saving code*/

        Dispatcher.BeginInvoke(() => { ObrazkiFinal.Add(fileName); });
     }
    }
}

А затем в XAML:

<ListBox Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="Auto" Name="lBox">
 <ListBox.ItemTemplate>
     <DataTemplate>
        <StackPanel>
              <Image Source="{Binding}"></Image>
        </StackPanel>
     </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>

и, конечно же, в PhoneApplicationPage:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

ObservableCollection успешно заполняется в потоке пользовательского интерфейса, так в чем же дело?

Добавлена ​​трассировка стека @edit:

в MS.Internal.XcpImports.CheckThread() в System.Windows.DependencyObject.GetValueInternal(DependencyProperty dp) в System.Windows.FrameworkElement.GetValueInternal(DependencyProperty dp) в System.Windows.DependencyObject.GetValue(DependencyProperty dp) в System.Windows .Controls.ItemsControl.get_ItemsSource() в myPhoneApp.MainPage.DownloadImageResult(результат IAsyncResult) в System.Net.Browser.ClientHttpWebRequest.‹>c_DisplayClassa.b_8(состояние объекта2) в System.Threading. ThreadPool.WorkItem.WaitCallback_Context(состояние объекта) в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Threading.ThreadPool.WorkItem.doWork(Object o) в System.Threading.Timer.ring( )


person szysz3kster    schedule 02.08.2011    source источник
comment
Не сразу понятно, откуда взялась ваша переменная fileName, поэтому для краткости вы удалили часть кода. Изменяет ли какой-либо из этих кодов коллекцию?   -  person Adam Robinson    schedule 02.08.2011
comment
Нет, единственная часть модифицирующей коллекции находится в DownloadImageResult (результат IAsyncResult).   -  person szysz3kster    schedule 02.08.2011


Ответы (1)


Согласно вашей трассировке стека, DownloadImageResult обращается к свойству ItemsSource (я предполагаю) вашего ListBox. Удалите это или переместите в блок BeginInvoke.

Для получения более конкретных советов опубликуйте полное содержание вашей функции DownloadImageResult.

person Adam Robinson    schedule 02.08.2011
comment
Отлично, спасибо за помощь. С ObservableCollection и ListBox все было в порядке. Я пытался получить доступ к IsolatedStorageFile.GetUserStoreForApplication(); вне диспетчера. - person szysz3kster; 02.08.2011
comment
@ szysz3kster это не похоже на настоящую причину проблемы. Изолированное хранилище доступно из любого потока, а не только из пользовательского интерфейса. - person Matt Lacey; 03.08.2011