C#UWP该应用程序调用了一个为不同线程编组的接口

时间:2016-12-20 01:25:22

标签: c# multithreading uwp

我有一个C#UWP应用程序,其中包含我想要每5秒调用一次的函数。 从按钮调用时该函数运行正常,并且Timer每5秒钟调试一次调试控制台....当我从Timer调用该函数时,所有函数都会松动。我明白了:

System.Exception未被用户代码处理 的HResult = -2147417842 Message =应用程序称为为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))

3 个答案:

答案 0 :(得分:7)

我认为您的功能会触及应用的用户界面。触摸UI的任何东西都需要在UI的调度程序线程上运行(大多数应用程序只有一个,直到你进入多个窗口应用程序)。

您可以使用Windows.UI.Xaml。DispatcherTimer在调度程序线程上运行计时器。

如果您需要在工作线程上运行代码然后触摸调度程序线程上的UI,您可以调用Dispatcher。RunAsync来将调用编组回调度程序线程。

您通常可以通过Window.Dispatcher从您的窗口中找到您的调度程序。

var ignored = Window.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
   // Do something on the dispatcher thread
});

答案 1 :(得分:0)

您最有可能使用Timer中的System.Threading。该计时器的事件不会被视为常规GUI事件,如果您从该计时器调用的方法访问GUI项,则会导致问题,因为该线程不是GUI项的所有者。

使用Timer中的System.Windows.Forms。该计时器可以访问您的GUI项目。

答案 2 :(得分:0)

您实际上可以使用Observable.Interval from Reactive Extensions并明确指定要在哪个调度程序上观察计时器事件:

Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.Default)
    .ObserveOn(coreWindow.Dispatcher)
    .Subscribe(_ => Log.Warning("Dispatcher.HasThreadAccess: " + coreWindow.Dispatcher.HasThreadAccess));

我喜欢这种方法的地方是,您明确说明在哪个线程上发生了什么(请参见SubscribeOn and ObserveOn)。