【问题标题】:'An outgoing call cannot be made since the application is dispatching an input-synchronous call. (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))''由于应用程序正在调度输入同步调用,因此无法进行传出调用。 (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))'
【发布时间】:2019-04-09 10:30:16
【问题描述】:

我对 C# 还很陌生,正在尝试为特定功能创建 Web 浏览器 我有调用 Form2(浏览器)的 Form1(一个不可见的表单)并监视以确保 Form2 始终在运行,如果它空闲关闭并重新打开 Form2

我认为我的线程有问题,我设置它来运行计时器(这是我可以解决的唯一方法)

我已经确定只有当我尝试从线程内部调用函数时它无法启动 Form2

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
using Browselite;
using System.Diagnostics;
using System.Threading;

namespace BrowseLite
{

    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool SetProcessDPIAware();

        public static Boolean IdleTimeoutEnabled { get; private set; }
        public static int IdleTimeout { get; private set; }
        public static Boolean ClearRunning { get; private set; }
        public Form2 Browser { get; private set; }
        public static Boolean programmaticClose { get; set; }
        public static Boolean Form2Open { get; set; }

        public Form1()
        {
            InitializeComponent();

        }


        [DllImport("user32.dll")]
        public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii);
        public struct tagLASTINPUTINFO
        {
            public uint cbSize;
            public Int32 dwTime;

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                using (RegistryKey RootKey = Registry.CurrentUser.OpenSubKey("Software\\Policies\\BrowseLite"))
                {
                    try
                    {

                        Form1.IdleTimeout = Int32.Parse(RootKey.GetValue("IdleTimeout", -1, RegistryValueOptions.None).ToString());
                        if (Form1.IdleTimeout <= 0)
                        {
                            Form1.IdleTimeoutEnabled = false;
                        }
                        else
                        {
                            Form1.IdleTimeoutEnabled = true;
                        }
                    }
                    catch
                    {
                        Form1.IdleTimeout = 0;
                        Form1.IdleTimeoutEnabled = false;
                    }

                }
            }
            catch
            {
                Form1.IdleTimeout = 0;
                Form1.IdleTimeoutEnabled = false;
            }


            Thread Timer = new Thread(new ThreadStart(MyTimer));

            Browser = new Form2();
            OpenBrowser();

            Timer.Start();
        }

        private void MyTimer()
        {
            while (true)
            {
                FormCollection OpenForms = Application.OpenForms;
                foreach (Form OpenForm in OpenForms)
                {
                    if (OpenForm.Name.Contains("Form2"))
                    {
                        Form1.Form2Open = true;
                    }
                }
                if (!Form1.Form2Open)
                {
                    Browser.ShowDialog();
                    Form1.Form2Open = true;
                }


                tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO();
                Int32 IdleTime;
                LastInput.cbSize = (uint)Marshal.SizeOf(LastInput);
                LastInput.dwTime = 0;

                if (GetLastInputInfo(ref LastInput))
                {
                    IdleTime = System.Environment.TickCount - LastInput.dwTime;
                    int IdleTimeSet = IdleTimeout * 60 * 1000;
                    if (Form1.IdleTimeoutEnabled)
                    {
                        if (IdleTime >= IdleTimeSet)
                        {
                            if (Form1.ClearRunning == false)
                            {
                                CloseBrowser();
                                OpenBrowser();
                            }
                        }
                        else
                        {
                            Form1.ClearRunning = false;
                        }
                    }
                }
                Thread.Sleep(1000 * 30); //Time in seconds (30)
            }
        }


        private void CloseBrowser()
        {
            Form1.programmaticClose = true;
            Browser.Close();
        }

        private void OpenBrowser()
        {
            Form1.programmaticClose = false;
            Form1.Form2Open = true;
            Browser.ShowDialog();
        }
    }
}

任何帮助将不胜感激,但正如我所说...我不擅长这个。

【问题讨论】:

  • 你为什么要使用这个叫做StartTimer的奇怪函数?你async await async await Task.Delay(1000) in infinitive loop。为什么不使用普通的Timer
  • 这看起来也是一个XY 问题。你想究竟做什么?为什么要关闭并重新打开空闲表单?为什么要使用 Browser 组件而不是普通的浏览器?
  • 我不知道为什么我最初使用这种方法。我刚刚更新了它,结果还是一样。我正在为信息亭机器开发浏览器。如果用户走开,它需要关闭浏览器并重新打开,以防万一他们愚蠢地登录到其中一个表单/站点
  • 为此有一个特殊的Windows Single-app Kiosk Mode。为什么不用它?
  • 在这种环境中使用 kiosk 方法有几个限制,这使得它对我们毫无用处。当我说制作 C# 应用程序不是我的第一偏好时,请相信我,但我已经接近终点线,我几乎可以品尝到它

标签: c#


【解决方案1】:

对于其他偶然发现此问题的人,我自己找到了答案

如果在线程中设置变量。而不是使用

Form1.Running = true;

改为使用

BeginInvoke(new Action(() => Form1.Running = true), null);

如果从线程中调用函数,则使用

BeginInvoke(new InvokeDelegate(FUNCTION));

这似乎完全解决了我的问题

【讨论】:

    猜你喜欢
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多