Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf ToListSync冻结用户界面_Wpf_Entity Framework_Async Await - Fatal编程技术网

Wpf ToListSync冻结用户界面

Wpf ToListSync冻结用户界面,wpf,entity-framework,async-await,Wpf,Entity Framework,Async Await,我有一个叫病人的模型: [Key] public Guid Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } 我的存储库返回所有患者(行数为1): 你知道为什么吗 谢谢所以我解决了这个问题,我正在使用callMethodOnLoadBehavior.cs。由于此行为不是作为等待任务执行的,因此它会阻塞UI 我必须做的是调用存储库调用GetPatientsAsyn

我有一个叫病人的模型:

[Key]
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
我的存储库返回所有患者(行数为1):

你知道为什么吗


谢谢

所以我解决了这个问题,我正在使用callMethodOnLoadBehavior.cs。由于此行为不是作为
等待任务执行的,因此它会阻塞UI

我必须做的是调用存储库调用
GetPatientsAsync
我将其包装在
任务中。运行(()=>_repository.GetPatientsAsync())

如果有更好的方法使用反射并能够调用
wait
,请告诉我

public class CallMethodOnLoadBehavior : Behavior<FrameworkElement>
{
    #region Properties
    public string MethodName
    {
        get { return (string)GetValue(MethodNameProperty); }
        set { SetValue(MethodNameProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MethodName.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MethodNameProperty =
        DependencyProperty.Register("MethodName", typeof(string), typeof(CallMethodOnLoadBehavior), new PropertyMetadata(null));

    public object TargetObject
    {
        get { return GetValue(TargetObjectProperty); }
        set { SetValue(TargetObjectProperty, value); }
    }

    // Using a DependencyProperty as the backing store for TargetObject.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TargetObjectProperty =
        DependencyProperty.Register("TargetObject", typeof(object), typeof(CallMethodOnLoadBehavior), new PropertyMetadata(null));
    #endregion

    #region Methods
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        if (AssociatedObject == null || string.IsNullOrWhiteSpace(MethodName) || TargetObject == null) return;
        var minfo = TargetObject.GetType().GetTypeInfo().GetDeclaredMethod(MethodName);
        if (minfo == null) return;
        minfo.Invoke(TargetObject, null);
    }
    #endregion
}
公共类CallMethodOnLoadBehavior:行为
{
#区域属性
公共字符串方法名
{
获取{return(string)GetValue(MethodNameProperty);}
set{SetValue(MethodNameProperty,value);}
}
//使用DependencyProperty作为MethodName的备份存储。这将启用动画、样式设置、绑定等。。。
公共静态只读DependencyProperty MethodNameProperty=
Register(“MethodName”、typeof(string)、typeof(CallMethodOnLoadBehavior)、newpropertyMetadata(null));
公共对象目标对象
{
获取{返回GetValue(TargetObject属性);}
set{SetValue(TargetObjectProperty,value);}
}
//使用DependencyProperty作为TargetObject的后备存储。这将启用动画、样式设置、绑定等。。。
公共静态只读从属属性TargetObjectProperty=
Register(“TargetObject”、typeof(object)、typeof(CallMethodOnLoadBehavior)、newpropertyMetadata(null));
#端区
#区域方法
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.Loaded+=已加载;
}
已加载专用void(对象发送方,RoutedEventArgs e)
{
if(AssociatedObject==null | | string.IsNullOrWhiteSpace(MethodName)| | TargetObject==null)返回;
var minfo=TargetObject.GetType().GetTypeInfo().GetDeclaredMethod(方法名);
if(minfo==null)返回;
Invoke(TargetObject,null);
}
#端区
}

您可以尝试将属性分配封送回UI线程。我不确定EF是如何工作的。我的直觉告诉我
ToListAsync()
是延迟加载的,这意味着当调用
FirstOrDefault()
时,返回值仍然从后台线程获取(因为您在存储库中等待调用),并且您尝试在主线程上分配和调用
OnPropertyChanged

public async Task LoadPatients()
{
      var s = await _repository.GetPatientsAsync();
      if (Patients != null) 
      {
          var patient = Patients.FirstOrDefault();
          Application.Dispatcher.Current.Invoke(() => SelectedPatient = patient);
      }
}

LoadPatients
从何处调用?它是从视图调用的,通过一个行为,请查看我下面关于解决问题的帖子。事实并非如此,当我逐步查看代码时,我清楚地看到在调用.toListSync()后有一个长时间的暂停。在查询之前禁用代理生成和懒散加载也不能解决问题。将其封送回UI也不能解决问题?因此这是我的实际代码:
public async void LoadPatients(){Patients=wait Task.Run(()=>_repository.GetPatientsAsync());if(Patients!=null)SelectedPatient=Patients.FirstOrDefault();}
之所以有效,是因为我将异步getpatients包装在task.run中。请参阅下面我的回答,以了解有关我如何准确致电患者的更多详细信息。
public class CallMethodOnLoadBehavior : Behavior<FrameworkElement>
{
    #region Properties
    public string MethodName
    {
        get { return (string)GetValue(MethodNameProperty); }
        set { SetValue(MethodNameProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MethodName.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MethodNameProperty =
        DependencyProperty.Register("MethodName", typeof(string), typeof(CallMethodOnLoadBehavior), new PropertyMetadata(null));

    public object TargetObject
    {
        get { return GetValue(TargetObjectProperty); }
        set { SetValue(TargetObjectProperty, value); }
    }

    // Using a DependencyProperty as the backing store for TargetObject.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TargetObjectProperty =
        DependencyProperty.Register("TargetObject", typeof(object), typeof(CallMethodOnLoadBehavior), new PropertyMetadata(null));
    #endregion

    #region Methods
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        if (AssociatedObject == null || string.IsNullOrWhiteSpace(MethodName) || TargetObject == null) return;
        var minfo = TargetObject.GetType().GetTypeInfo().GetDeclaredMethod(MethodName);
        if (minfo == null) return;
        minfo.Invoke(TargetObject, null);
    }
    #endregion
}
public async Task LoadPatients()
{
      var s = await _repository.GetPatientsAsync();
      if (Patients != null) 
      {
          var patient = Patients.FirstOrDefault();
          Application.Dispatcher.Current.Invoke(() => SelectedPatient = patient);
      }
}