I'm using winforms & reactive extension.
I'm using Observable.Timer inside my form.
When the timer fires, inside the callback an InvalidOperationException is raised when trying to invoke a method on any of the winform controls.
How can I fix this problem?
This is my code:
Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(2))
.Subscribe((e) =>
{
XXXXX();
});
You need to use the ObserveOn(form) method.
Install nuget package "System.Reactive.Windows.Forms"
Add ObserveOn(form) before the Subscribe() method:
Observable
.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(2))
.ObserveOn(this)
.Subscribe((e) =>
{
UpdateProcessStatus();
});
Related
Odd that I can't find anyone else that has encountered this issue.
In Visual Studio I have a few custom events that I fire and listen to between applications on the same page. The event names aren't important but here they are: 'dd.clear', 'dd.select', 'dd.switch'.
I get a tooltip warning "Cannot resolve event 'dd.clear'". How can I fix this? I can use Resharper's inspection tool to disable it but I'd like a better solution. Can I define my custom events somewhere and if so how?
Thanks.
Visual Studio basic JavaScript Snippets seems not to know custom events. Install vscode-standardjs-snippets and you should be fine.
Note that this tooltip warning is nothing realy important. It does not mean that your codes are broken.
The solution I came through is to use the actual type property of the event object :
class Model extends EventTarget {
static topicChangedEvent = new Event("topicChanged");
constructor() {
super();
this.topic = "";
}
setTopic(topic) {
if (this.topic === topic)
return;
this.topic = topic;
this.dispatchEvent(Model.topicChangedEvent);
}
}
const model = new Model();
/* ... */
model.addEventListener(Model.topicChangedEvent.type, () => ...);
In my MVVM based Wix Managed Bootstrapper application, while handling different events, I'm trying to show the user a view to get some input. It looks like Burn events are executing Asynchronously because using Dispatcher.Invoke(), it is skipping or passing by the view and hitting the last event, i.e not waiting for this input task to finish.
Here is the event handler which needs to finish before hitting last one:
Please note that when MessageBox.Show is popped, it waits until we close it. While debugging, I see it actually switched to MissingSourceView and loaded MissingSourceViewModel, but then while skipping it, and executes ApplyComplete();
BootstrapperApplication.ResolveSource += (sender, e) => {
System.Windows.Forms.MessageBox.Show("Inside ResolveSource");
WixBootstrapperData.CurrentDispatcher.Invoke(((Action)(() =>
{
WixBootstrapperData.CurrentViewModel = new MissingSourceViewModel(WixBootstrapperData, InfoMessage);
})));
};
BootstrapperApplication.ApplyComplete += (sender, e) =>
{
WixBootstrapperData.BootstrapperApplicationModel.FinalResult = e.Status;
WixBootstrapperData.CurrentDispatcher.Invoke((Action)(() =>
{
InfoMessage = AppResource.MsgFinished;
WixBootstrapperData.CurrentViewModel = new FinishViewModel(WixBootstrapperData, InfoMessage);
}
));
};
I guess, I should use await and async with ResolveSource(), but I face errors like:
Error CS1061 'BaseViewModel' does not contain a definition for
'GetAwaiter' and no extension method 'GetAwaiter' accepting a first
argument of type 'Task' could be found (are you missing a using
directive or an assembly reference?)
Any idea how to make it wait for finishing inside ResolveSource() and then jump to wherever it wants?
Use this, and please tell if this solves your problem.
WixBootstrapperData.CurrentDispatcher.Invoke(((Action)(() =>
{
Task.Factory.StartNew(() => {
WixBootstrapperData.CurrentViewModel = new MissingSourceViewModel(WixBootstrapperData, InfoMessage);
}).RunSynchronously();
})));
In my WP SignalR application I'm using this code:
_dataHub.Subscribe("ReceiveMessage").Received += list => App.RootFrame.Dispatcher.BeginInvoke(() => Messages.Add(list[0].ToString()));
But I have to use similar code to subscribe to my SignalR server application.
I tried this one:
_dataHub.Subscribe("ReceiveMessage").Received += list => Dispatcher.CurrentDispatcher.BeginInvoke(() => Messages.Add(list[0].ToString()));
I'm having delegate issue with that. Any help?
As described in error you are providing lambda expression instead of delegate. Use Action like this:
_dataHub.Subscribe("ReceiveMessage").Received += list =>
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() =>
Messages.Add(list[0].ToString())));
I am currently developing a WCF Publish Subscribe service. The subscriber is a winform app. As the subscriber needs to implement the callback method for the service, which in my case is the PostReceived() method, and the publisher has the PublishPost() method.
For the PostReceived() method for my winform, it is unable to access the UI thread of my winform. The subscribe method is done on my main method. How do I program my PostReceived() method in such a way that it is able to access the labels and such of my mainForm?
EDIT
what I have tried so far is calling the mainForm object from my program.cs but it crashes when i run all 3 , stating the error that it is unable to access the UI thread.
EDIT 2
I have tried using the following code but there is an error for it.
mainForm b;
public void PostReceived(string postSampleData)
{
b.BeginInvoke((MethodInvoker)delegate()
{
b.lblSearch.Text = "lakjslkaja";
});
After running the code, there is an error of
Object reference not set to an instance of an object.
Any idea how to fix it?
Your PostReceived method should be something like this
void PostReceived()
{
yourform.BeginInvoke((MethodInvoker)delegate()
{
yourform.button.Text = "new label";
//More stuff here
});
}
This will guarantee that all the stuff after BeginInvoke is invoked in the UI thread.
I have been developing a Silverlight user control for SharePoint using the Client Object model. Here is the coding
InitializeComponent();
ctx = ClientContext.Current;
Web web = ctx.Web;
ctx.Load(web, oweb => oweb.Title);
ctx.Load(web, oweb => oweb.Lists);
ctx.ExecuteQuery();
I heard tht SIlverlight supports both ExecuteQuery() and ExecuteQueryAsync() methods. But I'm getting an Exception message like this "he method or property that is called may block the UI thread and it is not allowed. Please use background thread to invoke the method or property, for example, using System.Threading.ThreadPool.QueueUserWorkItem method to invoke the method or property."
Can anyone tell me where am I going wrong and how to use ExecuteQuery() method ?? Thank you.
I might be off base here, but as I understand it, ExecuteQuery() requires you to create a thread so you aren't calling a stop to the UI thread when you invoke the method. The reason you use ExecuteQueryAsync is exactly that: ExecuteQueryAsync performs the operation on a seperate thread, then you just call back in to the UI thread using the dispather:
ctx.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
...
private void onQuerySucceeded(object sender, ClientRequestSucceededEventArgs args)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
doStuff();
}));
}