例外:应用程序调用了为不同线程编组的接口

时间:2015-01-23 13:33:31

标签: c# multithreading windows-store-apps async-await

private async void Button_Click(object sender, RoutedEventArgs e)
        {
            if (!AutoCompletions.Contains(Suggestions.Text) || !AutoCompletions.Contains(Suggestions1.Text))
            {
                MessageDialog messageDialog = new MessageDialog("Один или оба пункта не существует");
                messageDialog.ShowAsync();
                return;
            }
            Task<Train> getTrain=new Task<Train>(GetTrainSheldure);
            myIndeterminateProbar.Visibility = Visibility.Visible;
            try
            {
                this.Frame.Navigate(typeof (BlankPage3), await getTrain);
            }
            catch (Exception)
            {
                //handle the exception here
            }
            finally
            {
                myIndeterminateProbar.Visibility = Visibility.Visible;  
            }
        }



public Train GetTrainSheldure()
    {
        string date = DatePicker.Date.Year + "-" + DatePicker.Date.Month + "-" + DatePicker.Date.Day;
        return TrainGrabber.GetTrainSheldure(Suggestions.Text, Suggestions1.Text, date);
    }

我在行字符串uri = trainGrabber.GetUrl(Suggestions.Text,Suggestions1.Text,date)中遇到此错误;因为调用打开一个新线程,我该如何解决? 该应用程序调用了一个为不同线程编组的接口。

1 个答案:

答案 0 :(得分:0)

问题是您从新的GetTrainSheldure调用Task,这意味着它在线程池线程上执行。在该方法中,您尝试访问XAML控件(例如DatePicker),并且只能从UI线程访问XAML控件。

您是否有理由从GetTrainSheldure致电Task?例如,TrainGrabber.GetTrainSheldure是一项昂贵的操作吗?如果是这样,您应该从控件中捕获开始新Task之前的值。如果它不贵,那么只需删除Task的使用情况。

这样的事情:

// in Button_Click
var train = await GetTrainSheldure();

// method
public async Task<Train> GetTrainSheldure()
{
  var date = DatePicker.Date.Year // ... etc.
  var suggestion = Suggestions.Text
  var suggestion1 = Suggestions1.Text
  return Task.Run(()=>TrainGrabber.GetTrainSheldure(suggestion, suggestion1, date));
}

我没有运行此代码,但您应该能够让它运行起来。关键是您在创建Task 之前访问所有XAML控件