为什么线程只运行一次 - 打开和关闭窗口?

问题描述 投票:0回答:1

我试图在登录程序时打开“加载”窗口。一切都只能正确运行一次。第二次运行它时,出现错误:System.InvalidOperationException:调用线程无法访问此对象,因为它属于另一个线程。请帮忙...

ViewModel.cs

private ProszeCzekaj proszeCzekaj;

private async void ZalogujExecute(object obj)
{
    try
    {

        Thread tbr = new Thread(() =>
        {
            proszeCzekaj = new ProszeCzekaj();
            proszeCzekaj.Closed += (sender2, e2) =>
                proszeCzekaj.Dispatcher.InvokeShutdown();
            proszeCzekaj.Show();
            Dispatcher.Run();
        });
        tbr.SetApartmentState(ApartmentState.STA);  //required for WPF
        tbr.Start();

        var odp = await SprawdzLogowanie();
        if (odp==1)
        {
            
        }
        proszeCzekaj.Dispatcher.Invoke(proszeCzekaj.Window2Close);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

async Task<int> SprawdzLogowanie()
{
    await Task.Run(() =>
    {
        AplikacjaDbContext db = new AplikacjaDbContext();
        foreach (var user in db.UsersTable.ToList())
        {
            MessageBox.Show(user.userLogin); //for test
        }
    });
    
    return 1;
}

Logowani.xaml.cs

namespace PGSQL.View
{
    /// <summary>
    /// Logika interakcji dla klasy Logowanie.xaml
    /// </summary>
    public delegate void dWindow2Close();
    public partial class Logowanie : Window
    {
        public Logowanie()
        {
            InitializeComponent();

            LogowanieViewModel model = new LogowanieViewModel();
            this.DataContext = model;
        }
    }
}

正在加载.xaml.cs

namespace PGSQL.View
{
    /// <summary>
    /// Logika interakcji dla klasy ProszeCzekaj.xaml
    /// </summary>
    public partial class ProszeCzekaj : Window
    {
        public dWindow2Close Window2Close;

        public ProszeCzekaj()
        {
            InitializeComponent();
            Window2Close = new dWindow2Close(SecondWindowClose);

            IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
            var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
            var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
            DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));

            ProszeCzekajViewModel model = new ProszeCzekajViewModel();
            this.DataContext = model;
        }

        private void SecondWindowClose()
        {
            this.Close();
        }

        public enum DWMWINDOWATTRIBUTE
        {
            DWMWA_WINDOW_CORNER_PREFERENCE = 33
        }

        // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
        // what value of the enum to set.
        // Copied from dwmapi.h
        public enum DWM_WINDOW_CORNER_PREFERENCE
        {
            DWMWCP_DEFAULT = 0,
            DWMWCP_DONOTROUND = 1,
            DWMWCP_ROUND = 2,
            DWMWCP_ROUNDSMALL = 3
        }

        // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
        [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
        internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
                                                         DWMWINDOWATTRIBUTE attribute,
                                                         ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                         uint cbAttribute);
    }
}
c# multithreading xaml task
1个回答
0
投票

如果重用,Show方法预计会抛出异常。

无效操作异常
Show() 在正在关闭 (Closing) 或已关闭 (Closed) 的窗口上调用。

如果你想重复使用一个窗口,可能更好:

  • SecondWindowClose
    调用 Hide 而不是
    Close
  • 为了防止用户关闭
    ProszeCzekaj
    ,也许使用WindowStyle
© www.soinside.com 2019 - 2024. All rights reserved.