C# WPF - Accessing objects created on the UI thread from worker thread without blocking










0















I’m working on a plugin WPF application, which is instantiated from a larger application and regularly interfaces with the API of the main application. The problem I have is that my plugin UI is blocked whenever an intensive operation takes place interfacing with the main application.
In an attempt to resolve this I execute a task, and use the SynchronizationContext of the UI to call the operation which accesses the main application.
For test purposes I have simple WPF application MainWindow and set the ViewContext of the view model as follows



((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;


Then within my view model I perform the intensive operation from a task as follows.



public void BeginTaskWork()

Task.Factory.StartNew(() =>

ViewContext.Post(new SendOrPostCallback((o) =>

PerformIntensiveOperation();
), null);




This overcomes the obstacle of calling objects on the UI thread from a task but does not prevent the UI from hanging.



I suppose this is to be expected because I am still executing an intensive task on the UI thread.



So, basically I am asking if there is something I can do to prevent the UI from being blocked when I try to perform operations that interface with the parent application.



Update:



To clarify, the intensive operation involves accessing the API to the parent application and this is owned by the UI thread.



Also, when I simply attempt to perform this on another thread or task I get the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it." This is the reason I tried to the combination of a task and Synchronization context.



Thanks.










share|improve this question
























  • What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

    – FCin
    Nov 12 '18 at 12:25











  • You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

    – Nick
    Nov 12 '18 at 12:25











  • Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

    – user5265160
    Nov 12 '18 at 14:03















0















I’m working on a plugin WPF application, which is instantiated from a larger application and regularly interfaces with the API of the main application. The problem I have is that my plugin UI is blocked whenever an intensive operation takes place interfacing with the main application.
In an attempt to resolve this I execute a task, and use the SynchronizationContext of the UI to call the operation which accesses the main application.
For test purposes I have simple WPF application MainWindow and set the ViewContext of the view model as follows



((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;


Then within my view model I perform the intensive operation from a task as follows.



public void BeginTaskWork()

Task.Factory.StartNew(() =>

ViewContext.Post(new SendOrPostCallback((o) =>

PerformIntensiveOperation();
), null);




This overcomes the obstacle of calling objects on the UI thread from a task but does not prevent the UI from hanging.



I suppose this is to be expected because I am still executing an intensive task on the UI thread.



So, basically I am asking if there is something I can do to prevent the UI from being blocked when I try to perform operations that interface with the parent application.



Update:



To clarify, the intensive operation involves accessing the API to the parent application and this is owned by the UI thread.



Also, when I simply attempt to perform this on another thread or task I get the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it." This is the reason I tried to the combination of a task and Synchronization context.



Thanks.










share|improve this question
























  • What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

    – FCin
    Nov 12 '18 at 12:25











  • You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

    – Nick
    Nov 12 '18 at 12:25











  • Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

    – user5265160
    Nov 12 '18 at 14:03













0












0








0








I’m working on a plugin WPF application, which is instantiated from a larger application and regularly interfaces with the API of the main application. The problem I have is that my plugin UI is blocked whenever an intensive operation takes place interfacing with the main application.
In an attempt to resolve this I execute a task, and use the SynchronizationContext of the UI to call the operation which accesses the main application.
For test purposes I have simple WPF application MainWindow and set the ViewContext of the view model as follows



((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;


Then within my view model I perform the intensive operation from a task as follows.



public void BeginTaskWork()

Task.Factory.StartNew(() =>

ViewContext.Post(new SendOrPostCallback((o) =>

PerformIntensiveOperation();
), null);




This overcomes the obstacle of calling objects on the UI thread from a task but does not prevent the UI from hanging.



I suppose this is to be expected because I am still executing an intensive task on the UI thread.



So, basically I am asking if there is something I can do to prevent the UI from being blocked when I try to perform operations that interface with the parent application.



Update:



To clarify, the intensive operation involves accessing the API to the parent application and this is owned by the UI thread.



Also, when I simply attempt to perform this on another thread or task I get the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it." This is the reason I tried to the combination of a task and Synchronization context.



Thanks.










share|improve this question
















I’m working on a plugin WPF application, which is instantiated from a larger application and regularly interfaces with the API of the main application. The problem I have is that my plugin UI is blocked whenever an intensive operation takes place interfacing with the main application.
In an attempt to resolve this I execute a task, and use the SynchronizationContext of the UI to call the operation which accesses the main application.
For test purposes I have simple WPF application MainWindow and set the ViewContext of the view model as follows



((MainWindowViewModel)DataContext).ViewContext = SynchronizationContext.Current;


Then within my view model I perform the intensive operation from a task as follows.



public void BeginTaskWork()

Task.Factory.StartNew(() =>

ViewContext.Post(new SendOrPostCallback((o) =>

PerformIntensiveOperation();
), null);




This overcomes the obstacle of calling objects on the UI thread from a task but does not prevent the UI from hanging.



I suppose this is to be expected because I am still executing an intensive task on the UI thread.



So, basically I am asking if there is something I can do to prevent the UI from being blocked when I try to perform operations that interface with the parent application.



Update:



To clarify, the intensive operation involves accessing the API to the parent application and this is owned by the UI thread.



Also, when I simply attempt to perform this on another thread or task I get the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it." This is the reason I tried to the combination of a task and Synchronization context.



Thanks.







c# wpf multithreading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 14:14







user5265160

















asked Nov 12 '18 at 12:21









user5265160user5265160

86




86












  • What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

    – FCin
    Nov 12 '18 at 12:25











  • You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

    – Nick
    Nov 12 '18 at 12:25











  • Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

    – user5265160
    Nov 12 '18 at 14:03

















  • What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

    – FCin
    Nov 12 '18 at 12:25











  • You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

    – Nick
    Nov 12 '18 at 12:25











  • Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

    – user5265160
    Nov 12 '18 at 14:03
















What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

– FCin
Nov 12 '18 at 12:25





What you are doing right now is creating a task on a threadpool thread that schedules work on UI thread so obviously this will block. It's the same as just calling PerformIntensiveOperation()

– FCin
Nov 12 '18 at 12:25













You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

– Nick
Nov 12 '18 at 12:25





You may not be able to, if interfacing with the larger app demands you do so from the UI thread. Try to run your intensive operation from a regular task, and only update your UI from the synchronization context.

– Nick
Nov 12 '18 at 12:25













Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

– user5265160
Nov 12 '18 at 14:03





Thanks. I can't run the operation from a task, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it."

– user5265160
Nov 12 '18 at 14:03












1 Answer
1






active

oldest

votes


















0














Perform your intensive operation in another thread. This will not block the UI. If you need to call objects on UI thread from another thread than do exactly that - call them on UI thread. You can do this by doing an Invoke on current dispatcher.



await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());





share|improve this answer

























  • Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

    – user5265160
    Nov 12 '18 at 14:05












  • Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

    – Rob
    Nov 12 '18 at 14:11











  • I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

    – user5265160
    Nov 12 '18 at 15:06











  • When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

    – user5265160
    Nov 12 '18 at 17:30










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262104%2fc-sharp-wpf-accessing-objects-created-on-the-ui-thread-from-worker-thread-with%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Perform your intensive operation in another thread. This will not block the UI. If you need to call objects on UI thread from another thread than do exactly that - call them on UI thread. You can do this by doing an Invoke on current dispatcher.



await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());





share|improve this answer

























  • Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

    – user5265160
    Nov 12 '18 at 14:05












  • Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

    – Rob
    Nov 12 '18 at 14:11











  • I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

    – user5265160
    Nov 12 '18 at 15:06











  • When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

    – user5265160
    Nov 12 '18 at 17:30















0














Perform your intensive operation in another thread. This will not block the UI. If you need to call objects on UI thread from another thread than do exactly that - call them on UI thread. You can do this by doing an Invoke on current dispatcher.



await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());





share|improve this answer

























  • Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

    – user5265160
    Nov 12 '18 at 14:05












  • Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

    – Rob
    Nov 12 '18 at 14:11











  • I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

    – user5265160
    Nov 12 '18 at 15:06











  • When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

    – user5265160
    Nov 12 '18 at 17:30













0












0








0







Perform your intensive operation in another thread. This will not block the UI. If you need to call objects on UI thread from another thread than do exactly that - call them on UI thread. You can do this by doing an Invoke on current dispatcher.



await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());





share|improve this answer















Perform your intensive operation in another thread. This will not block the UI. If you need to call objects on UI thread from another thread than do exactly that - call them on UI thread. You can do this by doing an Invoke on current dispatcher.



await Application.Current.Dispatcher.BeginInvoke(() => SetPropertyOnUIThread());






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 '18 at 13:49

























answered Nov 12 '18 at 12:59









RobRob

1,0091022




1,0091022












  • Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

    – user5265160
    Nov 12 '18 at 14:05












  • Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

    – Rob
    Nov 12 '18 at 14:11











  • I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

    – user5265160
    Nov 12 '18 at 15:06











  • When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

    – user5265160
    Nov 12 '18 at 17:30

















  • Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

    – user5265160
    Nov 12 '18 at 14:05












  • Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

    – Rob
    Nov 12 '18 at 14:11











  • I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

    – user5265160
    Nov 12 '18 at 15:06











  • When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

    – user5265160
    Nov 12 '18 at 17:30
















Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

– user5265160
Nov 12 '18 at 14:05






Thanks for the suggestion. I can't run the operation on another thread, as this will produce the error "System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.". The intensive operation involves accesses to the main application API, which is owned by the UI thread. The application is a plugin.

– user5265160
Nov 12 '18 at 14:05














Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

– Rob
Nov 12 '18 at 14:11





Have you tried this? I am saying this because it seems like this solves the issue. You are getting this error because you are trying to update something between threads. This usually solves the problem. So for instance, if you have a view model that has a property that is binded to a progress level than changing this property from different thread will yield this error since the progress bar is owned by UI thread, BUT, if you call this property change on UI thread than it is okay.

– Rob
Nov 12 '18 at 14:11













I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

– user5265160
Nov 12 '18 at 15:06





I tried : await Application.Current.Dispatcher.BeginInvoke(new Action(() => PerformIntensiveOperation()));, however this still seems to block.

– user5265160
Nov 12 '18 at 15:06













When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

– user5265160
Nov 12 '18 at 17:30





When I run the WPF application on a separate thread, the above dispatcher invoke call works well and frees up the UI. This is a good solution to my problem because the application thread has direct access to the parent API.

– user5265160
Nov 12 '18 at 17:30

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262104%2fc-sharp-wpf-accessing-objects-created-on-the-ui-thread-from-worker-thread-with%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Darth Vader #20

Ondo