0

I know there are many posts about this error but the answers of them do not help me.

I have the problem that I use different classes in a WPF application. Additionally my redraw of the UI is in an own class (See code below).

Maybe someone can help me.

Short Example of code:

That is the mainWindow

namespace Project.View
{
  public partial class MainWindow : Window
  {
    public static MainWindow AppWindow;
    public static Thread MainWindowThread;
    private IShare iShare;
    public bool LoggedIn;
    public MainWindow()
    {
      InitializeComponent();
      MainWindowThread = Thread.CurrentThread;
      AppWindow = this;
      LoggedIn = false;
    }
    private void Login_Click(object sender, RoutedEventArgs e)
    {
      if(LoggedIn == true)
      {
        RedrawFunctions.Logout_default();
        LoggedIn = false;
      }
      else
      {
        iShare = new IShare(Username.Text, Password.Password, "...");
        iShare.StartConnection();
      }
    }
  }
}

That is the IShareLogin

namespace Project.Threads
{
  public class IShare
  {
    private static readonly object IShareLock = new object();
    private static IShareAccess IShare;
    private Thread Connect;
    private readonly string Username;
    private readonly string Password;
    private readonly string Domain;
    public event EventHandler StopErrorInfo;
    
    public IShareLogin(string IShareUsername, string ISharePassword, string IShareDomain)
    {
      Username = IShareUsername;
      Password = ISharePassword;
      Domain = IShareDomain;
    }
    public IShareLogin(){}
    public void StartConnection()
    {
      StopErrorInformation(EventArgs.Empty);
      Connect = new Thread(() => IShareConnect())
      {
        Name = "IShareLogin"
      };
      Connect.Start();
    }
    public void StopConnection()
    {
      StopErrorInformation(EventArgs,Empty);
      IShare = null;
    }
    private static void IShareConnect()
    {
      lock(IShareLock)
      {
        try
        {
          RedrawFunctions.LoginInformation_Content("Try to connect");
          RedrawFunctions.LoginInformation_BackgroundColor(Brushed.LightCyan);
          RedrawFunctions.LoginInformation_Visible(Visibility.Visible);
          IShare = new IShareAccess(Username, Password, Domain);
          RedrawFunctions.Login_default();
          MainWindow.AppWindow.LoggedIn = true;
          IShareLoginFailed.StopPreviews = false;
        }catch
        {
          IShareLoginFailed.LoginDataFalse();
        }
      }
    }
    protected virtual void StopErrorInformation(EventArgs e)
    {
      StopErrorInfo?.Invoke(this, e);
    }
  }
}

That is the IShareLogin failed

namespace Project.Threads
{
  public static class IShareLoginFailed
  {
    private static readonly Stopwatch ShowAlertTime = new Stopwatch();
    private static readonly IShareLogin EventIShare = new IShareLogin();
    private static bool WindowWollBeClosedSoon = false;
    private static bool TryLogin = false;
    private static SolidColorBrush Fill;
    private static readonly object LoginLock = new object();
    public static bool StopPreviews;
    
    public static void LoginDataFalse()
    {
      lock(LoginLock)
      {
        EventIShare.StopErrorInfo += new EventHandler(CancelToken);
        MainWindow.AppWindow.Closing += new 
        System.ComponentModel.CancelEventHandler(WindowCloses);
        MainWindow.AppWindow.Login_Button.Click += new RoutedEventHandler(LoginIsClicked);
        RedrawFunctions.LoginInformation_Content("Username or Password is wrong");
        Fill = new SolidColorBrush(Color.FromArgb(255, 255, 186, 186));
        RedrawFunctions.LoginInformation_BackgroundColor(Fill);
        RedrawFunctions.LoginInformation_Visible(Visibility.Visible);
        ShowAlertTime.Start();
        while(WindowWillBeClosedSoon == false && ShowAlertTime.ElapsedMilliseconds <= 5000)
        {
          if(TryLogin == true || StopPreviews == true)
          {
            break;
          }
          Thread.Sleep(50);
        }
        ShowAlertTime.Stop();
        ShowAlertTime.Reset();
        RedrawFunctions.LoginInformation_Visible(Visibility.Hidden);
        RedrawFunctions.LoginInformation_BackgroundColor(Brushes.Transparent);
        RedrawFunctions.LoginInformation_Content("");
        EventIShare.StopErrorInfo -= CancelToken;
        MainWindow.AppWindow.Closing -= WindowCloses;
        MainWindow.AppWindow.Login_Button.Click -= LoginIsClicked;
        TryLogin = false;
        RedrawFunctions.Logout_default();
      }
    }
    private static void WindowCloses(object sender, System.ComponentModel.CancelEventArgs e)
    {
      WindowWillBeClosedSoon = true;
    }
    private static void LoginIsClicked(object sender, RoutedEventArgs e)
    {
      TryLogin = true;
    }
    private static void CancelToken(object sender, EventArgs e)
    {
      StopPreviews = true;
    }
  }
}

That is the RadrawClass

namespace Project.View
{
  public partial class RedrawFunctions : MainWindow
  {
    public static void LoginInformation_Content(string name)
    {
      AppWindow.Dispatcher.Invoke(() => AppWindow.LoginInformation.Content = name);
    }
    public static void LoginInformation_Visible(Visibility Visible)
    {
      AppWindow.Dispatcher.Invoke(() => AppWindow.LoginInformation.Visibility = Visible);
    }
    public static void LoginInformation_BackgroundColor(Brush brushColor)
    {
      AppWindow.Dispatcher.Invoke(() => AppWindow.LoginInformation.Background = brushColor);
    }
  }
}

Maybe someone knows, how to clear this error. It occurs always, when the program calls the RedrawFunctions.LoginInformation_Visible function.

Thank you for your help.

jommil
  • 21
  • 7
  • 1
    You have to use your debugger to find out where the exception actually occurs. My bet would be that it is the LoginInformation_BackgroundColor method, not LoginInformation_Visible, because the passed Brush is an object with thread affinity that has to be frozen when it was created in a thread other than the UI thread. Try `Fill.Freeze()` before calling `RedrawFunctions.LoginInformation_BackgroundColor(Fill)`. – Clemens Jun 24 '21 at 10:16
  • 1
    Besides that, you should not be explicitly creating any Threads. Take a look at [Asynchronous programming with async and await](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/). – Clemens Jun 24 '21 at 10:21
  • Thank you for your help. This works fine for me. Maybe I was just looking for the wrong thing because the debugger always has been stopped after the "visible" function and not after the "backgroundcolor" function. – jommil Jun 24 '21 at 10:53

0 Answers0