Ehsan Akbar
Ehsan Akbar

Reputation: 7299

Start thread returns System.InvalidOperationException: The current SynchronizationContext may not be used as a TaskScheduler

I add a dashboard devexpress that run a stored procedure and it takes a long time. So I created a simple thread in my application in form_load

public void LoadDashboard()
{
    using (Stream s = new MemoryStream(Encoding.Default.GetBytes(Resource.Dashboard.MaterialDashboard1)))
    {
         s.Position = 0;
         dashboardViewer1.LoadDashboard(s);
    }
}

private void frmMaterialDashboard_Load(object sender, EventArgs e)
{
    Thread newth=new Thread(LoadDashboard);
    newth.Start();

    int UserId = int.Parse(Configuration.AccountDetail.UserId.ToString());
    lblUserName.Caption = _userRepository.Get().Where(i => i.Id == UserId).First().FullName;

    alertControl1.Show(this, "Welcome","Welcome to SPMS Mr."+_userRepository.FindById(Configuration.AccountDetail.UserId).First().FullName +"\n Server time:"+DateTime.Now);
}

But when I run my application I get this error :

An unhandled exception of type 'DevExpress.DashboardCommon.DashboardInternalException' occurred in DevExpress.Dashboard.v15.2.Win.dll

Additional information: Internal error. Please contact the application vendor or your system administrator and provide the following information.

System.InvalidOperationException: The current SynchronizationContext may not be used as a TaskScheduler.

at System.Threading.Tasks.SynchronizationContextTaskScheduler..ctor()
at DevExpress.DashboardWin.Native.WinDashboardService.RequestCustomizationServices(RequestCustomizationServicesEventArgs e)
at DevExpress.DashboardCommon.Service.DashboardService.DevExpress.DashboardCommon.Service.IDashboardServiceAdminHandlers.OnRequestCustomizationServices(Object sender, RequestCustomizationServicesEventArgs e)
at DevExpress.DashboardCommon.Server.DashboardSession.CreateDataLoaderParameters(ReloadDataArgs args) at DevExpress.DashboardCommon.Server.DashboardSession.CreateDataLoader(ReloadDataArgs args)
at DevExpress.DashboardCommon.Server.DashboardSession.LoadData(IEnumerable1 dataSourceComponentNames, ReloadDataArgs args)
at DevExpress.DashboardCommon.Server.DashboardSession.ReloadData(IEnumerable
1 dataSourceComponentNames, ReloadDataArgs args)
at DevExpress.DashboardCommon.Server.DashboardSession.Initialize(DashboardSessionState state, Boolean isDesignMode)
at DevExpress.DashboardCommon.Service.DashboardServiceOperation`1.Execute(DashboardServiceResult result)

Updated

I change my code like this, it works without any error and the data is shown but without any async operation and I have to wait to load data

public async Task<Stream> LoadDashboard()
{
    Stream s = new MemoryStream(Encoding.Default.GetBytes(Resource.Dashboard));
    s.Position = 0;
    return s;
}

private async void frmMaterialDashboard_Load(object sender, EventArgs e)
{
    Stream dashboardData = await LoadDashboard();
    dashboardViewer1.LoadDashboard(dashboardData);

    int UserId = int.Parse(Configuration.AccountDetail.UserId.ToString());
    lblUserName.Caption = _userRepository.Get().Where(i => i.Id == UserId).First().FullName;
    alertControl1.Show(this, "Welcome","Welcome to SPMS Mr."+_userRepository.FindById(Configuration.AccountDetail.UserId).First().FullName +"\n Server time:"+DateTime.Now);
}

Upvotes: 0

Views: 1175

Answers (1)

Serge Semenov
Serge Semenov

Reputation: 10052

Without full context of the problem I can't give you an exact solution, but overall, you cannot access UI elements from another thread. That means you need to do all request and computation on another thread, and then update UI elements on UI thread. Consider such simplified solution that does not explicitly start a new thread:

// event on UI thread    
private async void frmMaterialDashboard_Load(object sender, EventArgs e)
{
    var dashboardData = await LoadDashboardDataFromDatabaseAsync();
    dashboardViewer1.Load(dashboardData);
}

public async Task<DashboardData> LoadDashboardDataFromDatabaseAsync()
{
    string query = "...";
    var queryResult = await db.ExucuteQueryAsync(query).ConfigureAwait(false);
    return ConvertQueryRequltToDashboardData(queryResult);
}

Upvotes: 3

Related Questions