Hello, many thanks to everyone who answers!
So I myself got to the point where I can not figure it out, I ask for your help. There is such a code: in a nutshell, the application connects to the exchange program, which by means of the RTD interface in real time gives data about quotes and their updating, the problem is just in the update.
Outside, my UpdateNotify()
function is UpdateNotify()
class.
- How to build the logic of transferring control inside the application, provided one of the functions is called from the outside?
- Where should the code be transferred to the new thread under the same condition (calling one of the functions from the outside)?
- What should be considered when writing functions that are called from the outside?
There is such code:
<code> public partial class Form1 : Form { //ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠΈΠΏΠ° RtdClient RtdClient rtdClient; //ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠΈΠΏΠ° updateNotification RtdUpdate rtdUpdate; //ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ Form1 public Form1() { InitializeComponent(); var tosClassId = new Guid(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\myapp.COMApp.1\CLSID\", "", null).ToString()); rtdClient = new RtdClient(tosClassId, this); //ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΡΡΠ»ΠΊΡ Π½Π° Π½Π°Ρ ΠΊΠ»ΠΈΠ΅Π½Ρ, Π΄Π»Ρ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΉ rtdUpdate = new RtdUpdate(ref rtdClient); //ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π½Π°Ρ ΠΊΠ»ΠΈΠ΅Π½Ρ Π½Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ rtdClient.StartListenUpdate(ref rtdUpdate); } //ΡΡΠ½ΠΊΡΠΈΡ, ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π² ΠΌΠ°ΡΡΠΈΠ²Π°Ρ
, Π΅ΡΠ»ΠΈ ΠΏΡΠΈΡΠ»ΠΎ update public void UpdateOnePrice(object _inputSendDataToThread) { /* ΡΡΡ ΠΊΠΎΠ΄ ΠΊΠΎΡΠΎΡΡΠΉ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ */ } //ΠΊΠ»Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ RtdClient public class RtdClient { Form1 form; Type rtd; IRtdServer server; public RtdClient(Guid _serverId, Form1 _form) { form = _form; rtd = Type.GetTypeFromCLSID(_serverId); server = (IRtdServer)Activator.CreateInstance(rtd); } public void StartListenUpdate(ref RtdUpdate _rtdUpdate) { server.ServerStart(_rtdUpdate); } public void updateData() { try { var refresh = server.RefreshData(1); if (refresh.Length > 0) { sendDataToThread send = new sendDataToThread(); send.data[0, 0] = refresh[0, 0]; send.data[1, 0] = refresh[1, 0]; form.UpdateOnePrice(send); } } catch (Exception ex) { // TODO: Log exception MessageBox.Show("error:" + ex); } } } public class RtdUpdate : IRTDUpdateEvent { RtdClient rtdClient = null; ThreadManager threadManager; public delegate void MethodContainer(); public RtdUpdate(ref RtdClient _rtdClient) { rtdClient = _rtdClient; threadManager = new ThreadManager(); } public void UpdateNotify() { //ΡΠ·Π½Π°Π΅ΠΌ Π½ΠΎΠΌΠ΅Ρ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° int numThread = -1; while (numThread < 0) { numThread = threadManager.FreeThreadPlz(); } //Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π² ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠΌ ΠΏΠΎΡΠΎΠΊΠ΅ threadManager.threads[numThread] = new Thread(new ThreadStart(rtdClient.updateData)); threadManager.threads[numThread].Start(); } } //ΠΊΠ»Π°ΡΡ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΠΎΠΏΠΈΡΠ°ΡΡ, ΡΠΎ ΡΡΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ Π² Π½ΠΎΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ public class sendDataToThread { public object[,] data = new object[2, 1]; } //ΠΊΠ»Π°ΡΡ ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ public class ThreadManager { //ΠΊΠΎΠ»-Π²ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½Π½ΡΡ
ΠΏΠΎΡΠΎΠΊΠΎΠ² int threadCount = 10; //ΠΌΠ°ΡΡΠΈΠ² Ρ ΡΠ°Π±ΠΎΡΠΈΠΌΠΈ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ public Thread[] threads = new Thread[10]; //ΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΡΠΎΠΊ ΡΠ΅ΠΉΡΠ°Ρ ΡΠ²ΠΎΠ±ΠΎΠ΄Π΅Π½ public int FreeThread = 0; //ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ public ThreadManager() { Array.Resize(ref threads, threadCount); } public int FreeThreadPlz() { int i = 0; for (i = 0; i < threadCount; i++) { try { if (!threads[i].IsAlive) { return i; } } catch (Exception) { return i; } } /* LOG TO all BUSY THREAD */ return -1; } } //Π½ΠΈΠΆΠ΅ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠ² [ComImport, TypeLibType((short)0x1040), Guid("EC0E6191-DB51-11D3-8F3E-00C04F3651B8")] public interface IRtdServer { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10)] int ServerStart([In, MarshalAs(UnmanagedType.Interface)] IRTDUpdateEvent callback); [return: MarshalAs(UnmanagedType.Struct)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)] object ConnectData([In] int topicId, [In, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] ref object[] parameters, [In, Out] ref bool newValue); [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)] object[,] RefreshData([In, Out] ref int topicCount); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(13)] void DisconnectData([In] int topicId); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(14)] int Heartbeat(); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(15)] void ServerTerminate(); } //[ComImport, TypeLibType((short)0x1040), Guid("A43788C1-D91B-11D3-8F39-00C04F3651B8")] public interface IRTDUpdateEvent { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10), PreserveSig] void UpdateNotify(); /* [DispId(11)] int HeartbeatInterval { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)] get; [param: In] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)] set; } */ [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)] void Disconnect(); } }
UpdateNotify()
yourUpdateNotify()
function, it must first create an instance of theRtdUpdate
class, passing an instance ofRtdClient
. Try to make theRtdUpdate
class static or singleton. - iRumbaRtdUpdate
classRtdUpdate
passed as a parameter to theServerStart
method in the constructor. - Pavel Mayorov