Form中的Timer跨线程怎么调用?委托感觉思路对的但还是出错。

游荡的風 2014-04-06 01:14:07
具体代码如下,问题主要是如何在子线程把主线程的Timer控件打开。想了一晚上了没有头绪。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Timers;

namespace Server
{
public partial class Server : Form
{
public Server()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
}

private void Server_Load(object sender, EventArgs e)
{
//myEvent += new myDelegate(StartTimer);
}

//public void StartTimer()
//{
// ScreenTimer.Start();
//}

Thread MainThread;
Thread ScreenThread;
Socket socket;
byte[] bytePicture;
public string command;

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, //目标设备的句柄
int nXDest, //目标对象的左上角x坐标
int nYDest, //目标对象的左上角Y坐标
int nWidth, //目标对象的矩形宽度
int nHeight, //目标对象的矩形长度
IntPtr hdcSrc, //源设备的句柄
int nXSrc, //源对象的左上角x坐标
int nYSrc, //源对象的左上角y坐标
System.Int32 dwRop //光栅的操作值
);

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern IntPtr CreateDC(
string lpszDriver, //驱动名称
string lpszDevice, //设备名称
string lpszOutput, //无用,设为null
IntPtr lpInitData //任意的打印机数据
);

//获取Server的IP地址
public static IPAddress GetServerIP()
{
IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName());
return ieh.AddressList[0];
}

//public delegate void myDelegate();

//public event myDelegate myEvent;




//监听 端口:8888
private void BeginListen()
{
IPAddress ServerIp = GetServerIP();
IPEndPoint iep = new IPEndPoint(ServerIp, 8888);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(iep);
socket.Listen(10);



while (true)
{
try
{
byte[] CommandData = new byte[2];
Socket newSocket = socket.Accept();
newSocket.Receive(CommandData);
command = Encoding.Default.GetString(CommandData);
//判断命令
if (command == "00")//屏幕监控开启
{ //要在这个地方开启Timer,注释的是写的委托,运行后客户端无法
//if (myEvent != null) //与下方的9999端口连接。
//{ //如果用ScreenTimer.Enabled=true 或 ScreenTimer.start(),也是
// myEvent(); //这个错误
//} //如果只有ScreenMonitor() 和 ScreenSend()这两个函数,则没有错误
try //但是只能进行一次截屏发送操作,客户端也只能收到一次图片。
{

ScreenTimer.Enabled = true;
//ScreenMonitor();
//ScreenSend();
}
catch { }
}
else if (command == "01")
{
ScreenThread.Abort();//屏幕监控关闭
}
}
catch (System.Exception er)
{
}
}
}

//屏幕图像传输
private void ScreenSend()
{
while (true)
{
IPAddress ServerIp = GetServerIP();
IPEndPoint iep = new IPEndPoint(ServerIp, 9999);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(iep);
socket.Listen(10);

while (true)
{
try
{
Socket ScreenSocket = socket.Accept();
ScreenSocket.Send(bytePicture);
}
catch { }
}
}
}

//屏幕监控
private void ScreenMonitor()
{
/*Screen scr = Screen.PrimaryScreen;
Rectangle rc = scr.Bounds;
int iWidth = rc.Width;
int iHeight = rc.Height;
Size mySize = new Size(rc.Width, rc.Height);
Image bitmap = new Bitmap(iWidth, iHeight);

Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0,0,0,0,mySize);

bitmap.Save(@"c:/1.jpg");*/

IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);
//创建显示器DC
Graphics g1 = Graphics.FromHdc(dc1);
//由一个指定设备的句柄创建一个新的Graphics对象
Image MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
//根据屏幕大小创建一个与之相同大小的Bitmap对象
Graphics g2 = Graphics.FromImage(MyImage);
IntPtr dc3 = g1.GetHdc();
//获得屏幕的句柄
IntPtr dc2 = g2.GetHdc();
//获得位图的句柄
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);
//Bitblt(源场景,0,0,位图信息.位图宽度,位图信息.位图高度,桌面句柄,0,0,13369376) PS:SRCCOPY 13369376 将源矩形图象直接复制到目标矩形上
g1.ReleaseHdc(dc3);
//释放屏幕句柄
g2.ReleaseHdc(dc2);
//释放位图句柄
MyImage.Save("C:/MyJpeg.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

MemoryStream ms = new MemoryStream();
MyImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] bytes = ms.GetBuffer();
ms.Close();
bytePicture = bytes;
}


//屏幕定时器
public void ScreenTimer_Tick(object sender, EventArgs e)
{
ScreenMonitor();
ScreenSend();
}

//开启监听进程 BeginListen
private void StartServer_Click(object sender, EventArgs e)
{
try
{
MainThread = new Thread(new ThreadStart(BeginListen));
MainThread.Start();
}
catch (System.Exception er)
{
}
}

//关闭所有进程
private void StopServer_Click(object sender, EventArgs e)
{
try
{
socket.Close();
MainThread.Abort();
}
catch { }
}
}
}
...全文
112 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
本拉灯 2014-04-06
  • 打赏
  • 举报
回复
this.Invoke(new Action(()=>{
ScreenTimer.Enabled = true;
}));
游荡的風 2014-04-06
  • 打赏
  • 举报
回复
引用 1 楼 wyd1520 的回复:
this.Invoke(new Action(()=>{
ScreenTimer.Enabled = true;
}));
invoke是这么用的啊 谢谢 我是又添加了一个timer 设置了flag参数来控制的。

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧