Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用非主UI线程显示表单消息_C#_Multithreading_Forms_Websocket_Notifications - Fatal编程技术网

C# 使用非主UI线程显示表单消息

C# 使用非主UI线程显示表单消息,c#,multithreading,forms,websocket,notifications,C#,Multithreading,Forms,Websocket,Notifications,我有一个项目,没有使用任何表单/按钮或类似的东西,它与Websocket连接,并使用异步方法接收一些消息(在我自己创建的表单上),这些消息应该显示在屏幕的右上角 但是,如果websocket没有说它必须停止,则此消息可能会不时(2或3分钟)出现在屏幕上。这个消息可以足够大,为了让它看起来更好,我让我的消息以多种形式出现 这会给人一种通知的印象。因此,与websocket连接并接收消息async的类使用作为控制器的线程调用另一个类。控制器的目的是不时地在各种新的form()通知中显示该消息,如果w

我有一个项目,没有使用任何表单/按钮或类似的东西,它与Websocket连接,并使用异步方法接收一些消息(在我自己创建的表单上),这些消息应该显示在屏幕的右上角

但是,如果websocket没有说它必须停止,则此消息可能会不时(2或3分钟)出现在屏幕上。这个消息可以足够大,为了让它看起来更好,我让我的消息以多种形式出现

这会给人一种通知的印象。因此,与websocket连接并接收消息async的类使用作为控制器的线程调用另一个类。控制器的目的是不时地在各种新的form()通知中显示该消息,如果websocket不返回任何消息,则显然不会这样做

但是当我调用form.show时,程序停止工作。 我已经环顾了stackoverflow,但我发现的想法似乎不起作用

有人说我应该使用invoke,但它不断给出错误的说法 “在创建窗口句柄之前,无法对控件调用Invoke或BeginInvoke”,尝试这样解决:但它不起作用

有人说我应该使用.showDialog而不是.show,但它似乎不太好,因为它等待窗口关闭以终止该方法,正如我所说的,我需要同时打开多个通知

有人说表单是用.show打开的,但它只打开了很短的一段时间。但我没有注意到情况是否如此,即使如此,我也无法解决它。好吧,重要的是我被卡住了,我不知道该怎么做

编辑代码:

//Main
Application.Run(new SocketService());

//SocketService class
        public SocketService()
        {
            alerta = null;

            while (true)
            {
                try
                {
                    //Console.WriteLine("Nome do Usúario:" + Environment.UserName);
                    Thread.Sleep(2000);
                    Connect("ws://192.168.120.38:9091").Wait();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }

        public static async Task Connect(string uri)
        {
            ClientWebSocket webSocket = null;

            try
            {
                webSocket = new ClientWebSocket();
                await webSocket.ConnectAsync(new Uri(uri), CancellationToken.None);
                await Login(webSocket);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (webSocket != null)
                    webSocket.Dispose();

                lock (consoleLock)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("WebSocket closed.");
                    Console.ResetColor();
                }
            }
        }

        private static async Task Login(ClientWebSocket webSocket)
        {
            ArraySegment<Byte> buffer = new ArraySegment<byte>(encoder.GetBytes(        "{\"event\":\"loginBrowser\",\"data\":{\"login\":\"000000003077\",\"data\":\"1\"}}"));
            await webSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);

            if (webSocket.State == WebSocketState.Open)
            {
                if (ShowMessage.created != true)
                {
                    var dummy = new Control(); // to initialize SynchronizationContext
                    _sync = SynchronizationContext.Current;
                    new Thread(ThreadProc).Start();
                }

                await Receive(webSocket);               
            }

        }

        private static async Task Receive(ClientWebSocket webSocket)
        {
            while (webSocket.State == WebSocketState.Open)
            {
                ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[256]);
                var result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty,        CancellationToken.None);
                }
                else
                {
                    if (result.EndOfMessage)
                    {
                        message += encoder.GetString(buffer.ToArray());
                        SendMessage(message);
                    }
                    else
                    {
                        message += encoder.GetString(buffer.ToArray());
                    }
                }
            }
        }

        public static void ShowFormFromAnotherThread(string text)
        {
            _sync.Post(SendOrPostCallback, text);
        }

        private static void SendOrPostCallback(object state)
        {
            var form = new Notification();
            form.Text = (string)state;
            form.Show();
        }

        private static void ThreadProc()
        {
            while (true)
            {
                Thread.Sleep(2000); // wait imitation
                ShowFormFromAnotherThread("HI");
            }
        }

         /*Notification is my form and depending on where I put this part:
         var dummy = new Control(); // to initialize SynchronizationContext
        _sync = SynchronizationContext.Current;
        new Thread(ThreadProc).Start();
//Main
运行(新的SocketService());
//SocketService类
公共SocketService()
{
alerta=null;
while(true)
{
尝试
{
//WriteLine(“Nome do Usúario:+Environment.UserName”);
《睡眠》(2000年);
连接(“ws://192.168.120.38:9091”).Wait();
}
捕获(例外情况除外)
{
控制台写入线(ex);
}
}
}
公共静态异步任务连接(字符串uri)
{
ClientWebSocket-webSocket=null;
尝试
{
webSocket=新客户端webSocket();
等待webSocket.ConnectAsync(新Uri(Uri),CancellationToken.None);
等待登录(webSocket);
}
捕获(例外情况除外)
{
掷骰子;
}
最后
{
如果(webSocket!=null)
Dispose();
锁(控制台锁)
{
Console.ForegroundColor=ConsoleColor.Red;
Console.WriteLine(“WebSocket关闭”);
Console.ResetColor();
}
}
}
专用静态异步任务登录(ClientWebSocket webSocket)
{
ArraySegment buffer=新的ArraySegment(encoder.GetBytes(“{\”事件\“:\”登录\“,\”数据\“:{\”登录\“:\”000000003077\”,\”数据\“:\”1\”}”);
等待webSocket.SendAsync(缓冲区,WebSocketMessageType.Text,true,CancellationToken.None);
if(webSocket.State==WebSocketState.Open)
{
如果(ShowMessage.created!=true)
{
var dummy=new Control();//初始化SynchronizationContext
_sync=SynchronizationContext.Current;
新线程(ThreadProc.Start();
}
等待接收(webSocket);
}
}
专用静态异步任务接收(ClientWebSocket webSocket)
{
while(webSocket.State==WebSocketState.Open)
{
ArraySegment缓冲区=新的ArraySegment(新字节[256]);
var结果=等待webSocket.ReceiveAsync(缓冲区,CancellationToken.None);
if(result.MessageType==WebSocketMessageType.Close)
{
等待webSocket.CloseAsync(WebSocketCloseStatus.NormalClose,string.Empty,CancellationToken.None);
}
其他的
{
if(result.EndOfMessage)
{
message+=encoder.GetString(buffer.ToArray());
发送消息(message);
}
其他的
{
message+=encoder.GetString(buffer.ToArray());
}
}
}
}
另一个线程的公共静态void showForm(字符串文本)
{
_sync.Post(SendOrPostCallback,text);
}
私有静态void SendOrPostCallback(对象状态)
{
var form=新通知();
Text=(字符串)状态;
form.Show();
}
私有静态void ThreadProc()
{
while(true)
{
Thread.Sleep(2000);//等待模仿
显示来自另一个线程(“HI”);
}
}
/*通知是我的表格,取决于我把这部分放在哪里:
var dummy=新控件();//初始化SynchronizationContext的步骤
_sync=SynchronizationContext.Current;
新线程(ThreadProc.Start();
或者我没有调用login,或者没有输入receive()方法,或者它接收信息的最佳情况 从另一个线程调用threadProc和showForm,但不输入SednOrPostCallBack*/

尝试调用:

using System.Threading;
using System.Windows.Forms;

namespace ConsoleThreadSync
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Application.Run(new App());
        }
    }

    public class App : ApplicationContext
    {
        private readonly SynchronizationContext _sync;

        public App()
        {
            var dummy = new Control(); // to initialize SynchronizationContext
            _sync = SynchronizationContext.Current;
            new Thread(ThreadProc).Start();
        }

        public void ShowFormFromAnotherThread(string text)
        {
            _sync.Post(SendOrPostCallback, text);
        }

        private void SendOrPostCallback(object state)
        {
            var form = new Form1();
            form.Text = (string)state;
            form.Show();
        }

        private void ThreadProc()
        {
            while (true)
            {
                Thread.Sleep(2000); // wait imitation
                ShowFormFromAnotherThread("HI");
            }
        }
    }
}
var dummy = new Control(); // to initialize SynchronizationContext
_sync = SynchronizationContext.Current;
从构造函数SocketService()而不是从
namespace ReiDoCSharp
{
    class ShowMessage
    {
        private static RootObject alerta;
        public static bool created;
        private static int startPosition;

        public static void setStartPosition(int start)
        {
            if (start < startPosition)
            {
                startPosition = start;
            }
        }

        public RootObject getAlerta()
        {
            return ShowMessage.alerta;
        }

        public void setAlerta(RootObject root)
        {
            ShowMessage.alerta = root;
        }

        private static void DoWork()
        {
            while (true)
            {
                if (created != true)
                {
                    created = true;
                }

                if (alerta != null)
                {
                    string mensagem = "";

                    if ((alerta.data.Informacoes[1] != "") && (alerta.data.Informacoes[1] != null))
                    {
                        mensagem += alerta.data.Informacoes[1];
                    }

                    if ((alerta.data.Informacoes[0] != "") && (alerta.data.Informacoes[0] != null))
                    {
                        mensagem += alerta.data.Informacoes[0];
                    }

                    if (mensagem != "")
                    {
                        startPosition = 5;


                        string[] messages = mensagem.Split(new[] { "<br><br>" }, StringSplitOptions.None);
                        foreach (string message in messages)
                        {

                            Notification popup = new Notification();
                            popup.label1.Text = message;
                            popup.TopMost = true;
                            popup.Show();
                            Application.DoEvents();
                            /*Solution with the ShowDialog would be:
                                Task.Run(() => showNotification(message));
                            */
                        }
                    }
                }

                Thread.Sleep(5000);
            }
        }

        //Then I won't need to use Application.DoEvents, but would have to create more threads
        private static Task showNotification(string message)
        {
            Notification popup = new Notification();
            popup.label1.Text = message;
            popup.TopMost = true;
            popup.ShowDialog();
        }

        public static Task createPopupsAsync()
        {
            Task.Run(() => DoWork());
        }
    }

}

namespace ReiDoCSharp
{
    class SocketService
    {
        private static object consoleLock = new object();
        private const bool verbose = true;
        private static readonly TimeSpan delay = TimeSpan.FromMilliseconds(3000);
        private static UTF8Encoding encoder = new UTF8Encoding();
        private static string message;
        private static RootObject alerta;

        public SocketService()
        {
            Begin();
        }

        public static void Begin()
        {
            alerta = null;

            while (true)
            {
                try
                {
                    Thread.Sleep(2000);
                    Connect("ws://192.168.120.38:9091").Wait();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }

        public static async Task Connect(string uri)
        {
            ClientWebSocket webSocket = null;

            try
            {
                webSocket = new ClientWebSocket();
                await webSocket.ConnectAsync(new Uri(uri), CancellationToken.None);
                await Login(webSocket);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (webSocket != null)
                    webSocket.Dispose();

                lock (consoleLock)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("WebSocket closed.");
                    Console.ResetColor();
                }
            }
        }

        private static async Task Login(ClientWebSocket webSocket)
        {
            ArraySegment<Byte> buffer = new ArraySegment<byte>(encoder.GetBytes("{\"event\":\"loginBrowser\",\"data\":{\"OPERADOR\":\"000000003077\",\"NRORG\":\"1\"}}"));
            await webSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);

            if (webSocket.State == WebSocketState.Open)
            {
                Task.Factory.StartNew(() => ShowMessage.createPopupsAsync());
                await Receive(webSocket);
            }
        }

        private static async Task Receive(ClientWebSocket webSocket)
        {
            while (webSocket.State == WebSocketState.Open)
            {
                ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[256]);
                var result = await webSocket.ReceiveAsync(buffer, CancellationToken.None);

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
                }
                else
                {
                    if (result.EndOfMessage)
                    {
                        message += encoder.GetString(buffer.ToArray());
                        SendMessage(message);
                    }
                    else
                    {
                        message += encoder.GetString(buffer.ToArray());
                    }
                }
            }
        }

        private static void LogStatus(bool receiving, byte[] buffer, int length, string assunto)
        {
            lock (consoleLock)
            {
                Console.ForegroundColor = receiving ? ConsoleColor.Green : ConsoleColor.Yellow;

                if (verbose)
                {
                    Console.WriteLine(encoder.GetString(buffer) + "  " + assunto);
                }

                Console.ResetColor();
            }
        }

        private static void SendMessage(string message)
        {
            message = message.Replace("event", "evento");
            message = message.Replace("\0", "");

            JavaScriptSerializer js = new JavaScriptSerializer();
            RootObject mess = js.Deserialize<RootObject>(message);

            if (mess.data.Informacoes[1] != "")
            {
                mess.data.Informacoes[1] += "<br>";
            }

            if (alerta == null)
            {
                alerta = mess;
            }
            else
            {
                if ((mess.data.Quantidade[0] != 0) && (mess.data.Quantidade == null))
                {
                    if ((mess.data.Quantidade[0] == -1) && (mess.data.Informacoes[0] == ""))
                    {
                        alerta = null;
                    }
                    else
                    {
                        alerta = mess;
                    }
                }
                else if (mess.data.Quantidade[0] == 0)
                {
                    alerta = null;
                }

                if ((mess.data.Quantidade[1] != 0) && (mess.data.Informacoes[1] != ""))
                {
                    alerta = mess;
                }
            }

            new ShowMessage().setAlerta(alerta);
            message = "";
        }

    }
}