现用C#开发一大型程序,数据操作量较大耗时太长,打算采用多线程提高效率那为仁兄有多线程方面比较成熟和实用的代码给一个,谢谢!mail:[email protected]
解决方案 »
- webbrowser 拖动选中文本到文本框
- CheckedListBox 的小问题
- 再次请教了 其实和上两个问题 相关 Datagridview 的refresh 和invalidate 方法 为何无效?
- socket编程使用序列化,我想把一个树TreeView序列化传送 怎么提示错误呢
- 请教工资系统数据库中的数据类型?
- 关于Nhibernate的一些疑问
- 一个很菜的问题,二进制文件中的数据总是反的
- 有关reflector反编译C#程序及其他相关问题,急
- web C# datagrid 如何绑定数据库数据 望详细
- 如何在FileStream中读出(显示)正确字符?
- ftp下载的问题
- 关于读写XML文件
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;
using System.Collections;namespace AutoMessager
{
delegate void myDelegate();
delegate void SetTextCallback(string text); public partial class frmAutoMsg : Form
{
event myDelegate myEvent;
string connStr = string.Empty;
Thread thd;
//private Icon eyeIcon; //private NotifyIconEx notifyIconA;
//private NotifyIconEx notifyIconB;
private bool canClosed = false; public frmAutoMsg()
{
this.ShowInTaskbar = false;
InitializeComponent();
//eyeIcon = new Icon(GetType(), "EYE.ICO");
notifyIcon1.ContextMenu = contextMenuB;
} private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.txtMsgStatus.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.txtMsgStatus.Text += text;
}
}
private void frmAutoMsg_Load(object sender, EventArgs e)
{
connStr = System.Configuration.ConfigurationManager.AppSettings["ConnString"];
thd = new Thread(new ThreadStart(doEvent));
thd.IsBackground = true;
thd.Start();
//doEvent();
//notifyIcon1.Visible = true;
} /// <summary>
/// 员工合同到期提醒
/// </summary>
void UpUserState()
{
try{
//数据库操作 省略... :)
SetText("\r\n系统提示: 职员合同消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
catch (Exception ex)
{
dr.Close();
tran.Rollback();
SetText("\r\n系统错误: 职员合同消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
dr.Close();
conn.Close();
conn.Dispose();
}
}
/// <summary>
/// 采购及供货 到货提醒
/// </summary>
void UpCaiGou()
{
try{
//数据库操作 省略... :)
SetText("系统提示: 合同采购消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
catch (Exception ex)
{
dr.Close();
tran.Rollback();
SetText("系统错误: 合同采购消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
dr.Close();
conn.Close();
conn.Dispose();
}
} /// <summary>
/// 供货收款情况提醒
/// </summary>
void GetMoney()
{
try{ //数据库操作 省略... :)
SetText("系统提示: 供货付款消息更新成功!\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
catch (Exception ex)
{
SetText("系统错误: 供货付款消息更新错误:" + ex.Message + "\r\n");
SetText("执行时间:" + now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
}
finally
{
conn.Close();
conn.Dispose();
}
} void doEvent()
{
while (true)
{ //DateTime now = DateTime.Now;
int i = DateTime.Now.Hour;
if (i > 2 && i < 4)
{
myEvent = new myDelegate(UpUserState);
myEvent += new myDelegate(UpCaiGou);
// myEvent += new myDelegate(GetMoney);
}
//if (now.Hour == 3)
//{
// myEventB = new myDelegate(deltemp);
//}
//if (myEventA != null) myEventA();
//if (myEventB != null) myEventB();
if (myEvent != null)
{
myEvent();
myEvent = null;
}
Application.DoEvents();
Thread.Sleep(6000000); //每100分钟检查一次时间
}
} private void frmAutoMsg_FormClosing(object sender, FormClosingEventArgs e)
{
if (canClosed == false)
{
e.Cancel = true;
this.Hide();
this.Visible = false;
//this.
}
} private void menuItem2_Click(object sender, EventArgs e)
{
this.ShowInTaskbar = true;
this.Show();
this.Visible = true; //恢复主窗体
} private void menuItem1_Click(object sender, EventArgs e)
{
canClosed = true;
Application.Exit();
} private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.ShowInTaskbar = true;
this.Show();
if (this.Visible == false)
{
this.Visible = true;
} } private void btnClear_Click(object sender, EventArgs e)
{
this.txtMsgStatus.Text = "";
} private void btnUpMsg_Click(object sender, EventArgs e)
{
myEvent = new myDelegate(UpUserState);
myEvent += new myDelegate(UpCaiGou);
//myEvent += new myDelegate(GetMoney); if (myEvent != null)
myEvent();
}
}
}
using System;
using System.Threading; // Simple threading scenario: Start a static method running
// on a second thread.
public class ThreadExample {
// The ThreadProc method is called when the thread starts.
// It loops ten times, writing to the console and yielding
// the rest of its time slice each time, and then ends.
public static void ThreadProc() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("ThreadProc: {0}", i);
// Yield the rest of the time slice.
Thread.Sleep(0);
}
}
public static void Main() {
Console.WriteLine("Main thread: Start a second thread.");
// The constructor for the Thread class requires a ThreadStart
// delegate that represents the method to be executed on the
// thread. C# simplifies the creation of this delegate.
Thread t = new Thread(new ThreadStart(ThreadProc));
// Start ThreadProc. On a uniprocessor, the thread does not get
// any processor time until the main thread yields. Uncomment
// the Thread.Sleep that follows t.Start() to see the difference.
t.Start();
//Thread.Sleep(0);
for (int i = 0; i < 4; i++) {
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(0);
}
Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.");
t.Join();
Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.");
Console.ReadLine();
}
}
此代码产生的输出类似如下内容: Main thread: Start a second thread.
Main thread: Do some work.
ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Call Join(), to wait until ThreadProc ends.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
Main thread: ThreadProc.Join has returned. Press Enter to end program.
【文章作者】: 有酒醉
【作者邮箱】: [email protected]
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
三、同步变量访问
数据同步容易造成数据的破坏.虽然说数据同步可能会破坏我们的程序,但是它不会破坏类型安全性.这是因为装载诸如指针等基本类型总是基本操作,所以不会破坏托管指针和对象引用.
lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁.我们先研究下lock的内部实现方式
// LockDemo.cs
// Author by Yzlusing System;
using System.Threading;public class LockDemo
...{
public static void Main(string[] args)
...{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),"Yzl01");
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),"Yzl02");
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),"Yzl03");
Console.ReadLine();
}
private static void ThreadProc(object state)
...{
Thread.Sleep(500);
Console.WriteLine("Current Object:"+state);
lock(x.GetType())
...{
x = System.AppDomain.GetCurrentThreadId();
Console.WriteLine("x="+x);
}
}
private static int x ;
}
编译运行:
E:\>csc LockDemo.cs
E:\>LockDemo
Current Object:Yzl01
x=2212
Current Object:Yzl02
x=2212
Current Object:Yzl03
x=2444
exit
反汇编查看内部结构:
IL_001a: ldsfld int32 LockDemo::x
IL_001f: box [mscorlib]System.Int32
IL_0024: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0029: dup
IL_002a: stloc.0
IL_002b: call void [mscorlib]System.Threading.Monitor::Enter(object)
.try
...{
IL_0030: call int32 [mscorlib]System.AppDomain::GetCurrentThreadId()
IL_0035: stsfld int32 LockDemo::x
IL_003a: ldstr "x="
IL_003f: ldsfld int32 LockDemo::x
IL_0044: box [mscorlib]System.Int32
IL_0049: call string [mscorlib]System.String::Concat(object, object)
IL_004e: call void [mscorlib]System.Console::WriteLine(string)
IL_0053: leave.s IL_005c} // end .try
finally
...{
IL_0055: ldloc.0
IL_0056: call void [mscorlib]System.Threading.Monitor::Exit(object) IL_005b: endfinally
} // end handler
我们很容易观察出lock实际上是应用了Monitor来进行同步变量的访问.同时也注意到了Monitor::Exit(object)放在finally中保证了同步锁的释放.
C++中没有等效于C# lock 语句,如果用C++编写代码,那么需要显式调用Monitor方法.
示例 -- C++ 中应用lock
// CLockDemo.cpp
// Author by Yzl#using < mscorlib.dll >
using namespace System;
using namespace System::Threading;#pragma managed
__gc class CLockDemo
...{
public:
static void ThreadProc(Object* state)
...{
Thread::Sleep(1000);
Console::WriteLine(S"Current Object:{0}",state->ToString());
Object *iObj = __box(x);
Type *iType = iObj->GetType();
try
...{
//Lock the x
Monitor::Enter(iType);
x = AppDomain::GetCurrentThreadId();
Console::WriteLine(S"x={0}",x.ToString());
}
catch(Exception *ex)
...{
Console::WriteLine(ex->ToString());
}
__finally
...{
Monitor::Exit(iType);
}
}
private:
static int x;
};#pragma managed
int main(void)
...{
ThreadPool::QueueUserWorkItem(new WaitCallback(0,CLockDemo::ThreadProc),new String("Yzl01"));
ThreadPool::QueueUserWorkItem(new WaitCallback(0,CLockDemo::ThreadProc),new String("Yzl02"));
ThreadPool::QueueUserWorkItem(new WaitCallback(0,CLockDemo::ThreadProc),new String("Yzl03"));
Console::ReadLine();
}
编译运行:
E:\>cl ClockDemo.cpp /clr
E:\>CLockDemo
Current Object:Yzl01
x=2644
Current Object:Yzl02
x=2660
Current Object:Yzl03
x=2644
exit
我们将Monitor::Exit(iType)注释掉,观察一下会有什么结果:
E:\>cl ClockDemo.cpp /clr
E:\>ClockDemo
Current Object:Yzl01
x=2672
Current Object:Yzl02
Current Object:Yzl03
x=2672
到这里程序无法运行下去,停滞不前.这是由于2672号线程并未释放对象锁所造成的.同时我们也发现Object:Yzl01,Object:Yzl03采用了同一线程池中的线程运行自己的任务.
<续>
--------------------------------------------------------------------------------
【版权声明】: 本文原创于厦门, 转载请注明作者并保持文章的完整, 谢谢! 2007年03月01日 14:10:15嘿嘿....
smartthreadpool