326 .net c# multithreading
我有一些代码需要在与GUI不同的线程中运行,因为它当前导致表单在代码运行时冻结(10秒左右).
假设我以前从未创建过新的线程; 什么是如何在C#中使用.NET Framework 2.0或更高版本执行此操作的简单/基本示例?
Ed *_*wer 322
Joe Albahari是开始阅读的好地方.
如果你想创建自己的线程,这很简单:
using System.Threading;
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
/* run your code here */
Console.WriteLine("Hello, world");
}).Start();
Run Code Online (Sandbox Code Playgroud)
Gan*_*ant 192
BackgroundWorker 似乎是你的最佳选择.
这是我的最小例子.单击按钮后,后台工作程序将开始在后台线程中工作,并同时报告其进度.它还将在工作完成后报告.
using System.ComponentModel;
...
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
// this allows our worker to report progress during work
bw.WorkerReportsProgress = true;
// what to do in the background thread
bw.DoWork += new DoWorkEventHandler(
delegate(object o, DoWorkEventArgs args)
{
BackgroundWorker b = o as BackgroundWorker;
// do some simple processing for 10 seconds
for (int i = 1; i <= 10; i++)
{
// report the progress in percent
b.ReportProgress(i * 10);
Thread.Sleep(1000);
}
});
// what to do when progress changed (update the progress bar for example)
bw.ProgressChanged += new ProgressChangedEventHandler(
delegate(object o, ProgressChangedEventArgs args)
{
label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
});
// what to do when worker completes its task (notify the user)
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
delegate(object o, RunWorkerCompletedEventArgs args)
{
label1.Text = "Finished!";
});
bw.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
注意:
ProgressChanged或
RunWorkerCompleted处理程序中更新GUI是安全的
.但是,更新GUI DoWork
将导致
InvalidOperationException.Mar*_*ett 99
该ThreadPool.QueueUserWorkItem是相当理想的简单的东西.唯一需要注意的是从另一个线程访问一个控件.
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
DoSomethingThatDoesntInvolveAControl();
}, null);
Run Code Online (Sandbox Code Playgroud)
Fal*_*tar 75
快速又脏,但它会起作用:
在顶部使用:
using System.Threading;
Run Code Online (Sandbox Code Playgroud)
简单代码:
static void Main( string[] args )
{
Thread t = new Thread( NewThread );
t.Start();
}
static void NewThread()
{
//code goes here
}
Run Code Online (Sandbox Code Playgroud)
我把它扔进了一个新的控制台应用程序中
Spo*_*ade 62
这是另一种选择:
Task.Run(()=>{
//Here is a new thread
});
Run Code Online (Sandbox Code Playgroud)
And*_*ndy 40
尝试使用BackgroundWorker类.您可以为代理人提供运行的内容,并在工作完成时收到通知.我链接到的MSDN页面上有一个示例.
小智 14
如果你想得到一个值:
var someValue;
Thread thread = new Thread(delegate()
{
//Do somthing and set your value
someValue = "Hello World";
});
thread.Start();
while (thread.IsAlive)
Application.DoEvents();
Run Code Online (Sandbox Code Playgroud)
将该代码放在一个函数中(无法在与GUI相同的线程上执行的代码),并触发该代码的执行,如下所示.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
在线程对象上调用start函数将导致在新线程中执行函数调用.
如果要使用原始 Thread 对象,那么您至少需要将 IsBackground 设置为 true,并且还应该设置 Threading Apartment 模型(可能是 STA)。
public static void DoWork()
{
// do some work
}
public static void StartWorker()
{
Thread worker = new Thread(DoWork);
worker.IsBackground = true;
worker.SetApartmentState(System.Threading.ApartmentState.STA);
worker.Start()
}
Run Code Online (Sandbox Code Playgroud)
如果您需要 UI 交互,我会推荐 BackgroundWorker 类。
小智 5
在这里,如何将线程与progressBar结合使用,仅用于了解线程的工作方式,形式为三个progressBar和4个按钮:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Thread t, t2, t3;
private void Form1_Load(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
t = new Thread(birinicBar); //evry thread workes with a new progressBar
t2 = new Thread(ikinciBar);
t3 = new Thread(ucuncuBar);
}
public void birinicBar() //to make progressBar work
{
for (int i = 0; i < 100; i++) {
progressBar1.Value++;
Thread.Sleep(100); // this progressBar gonna work faster
}
}
public void ikinciBar()
{
for (int i = 0; i < 100; i++)
{
progressBar2.Value++;
Thread.Sleep(200);
}
}
public void ucuncuBar()
{
for (int i = 0; i < 100; i++)
{
progressBar3.Value++;
Thread.Sleep(300);
}
}
private void button1_Click(object sender, EventArgs e) //that button to start the threads
{
t.Start();
t2.Start(); t3.Start();
}
private void button4_Click(object sender, EventArgs e)//that button to stup the threads with the progressBar
{
t.Suspend();
t2.Suspend();
t3.Suspend();
}
private void button2_Click(object sender, EventArgs e)// that is for contuniue after stuping
{
t.Resume();
t2.Resume();
t3.Resume();
}
private void button3_Click(object sender, EventArgs e) // finally with that button you can remove all of the threads
{
t.Abort();
t2.Abort();
t3.Abort();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
395140 次 |
| 最近记录: |