class MyThread
{
public string SharedData;
public void Worker()
{
...lengthy action, infinite loop, etc...
SharedData = "whatever";
...lengthy action...
return;
}
}
class Program
{
static void Main()
{
MyThread m = new MyThread();
Thread WorkerThread = new Thread(m.Worker);
WorkerThread.Start();
loop//or e.g. a Timer thread
{
f(m.SharedData);
}
return;
}
}
你可以在 this nice introduction about multithreading中读到这个方法,但是,我更喜欢在 O'Reilly book C# 3.0 in a nutshell中读到这个方法,由 Albahari 兄弟(2007) ,它也可以在 Google Books 上免费访问,就像这本书的新版本一样,因为它也涵盖了线程池,前景线程与背景线程等等,有漂亮而简单的示例代码。(免责声明: 我拥有一本破旧的这本书)
我有一个特殊的问题,我想使用项目,包含控件,从一个集成测试套件,所以必须创建一个 STA 线程。我最终得到的代码如下所示,放在这里是为了防止其他代码出现同样的问题。
public Boolean? Dance(String name) {
// Already on an STA thread, so just go for it
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) return DanceSTA(name);
// Local variable to hold the caught exception until the caller can rethrow
Exception lException = null;
Boolean? lResult = null;
// A gate to hold the calling thread until the called thread is done
var lGate = new ManualResetEvent(false);
var lThreadStart = new ThreadStart(() => {
try {
lResult = DanceSTA(name);
} catch (Exception ex) {
lException = ex;
}
lGate.Set();
});
var lThread = new Thread(lThreadStart);
lThread.SetApartmentState(ApartmentState.STA);
lThread.Start();
lGate.WaitOne();
if (lException != null) throw lException;
return lResult;
}
public Boolean? DanceSTA(String name) { ... }
class Program
{
static void Main(string[] args)
{
CancellationTokenSource cancelToken = new CancellationTokenSource();
Exception taskException = null;
var timerTask = Task.Factory.StartNew(() =>
{
for (;;)
{
if (cancelToken.IsCancellationRequested)
break;
ContinuousTask();
Thread.Sleep(400);
}
}, cancelToken.Token).ContinueWith((t, o) => {
taskException = t.Exception;
((Thread)o).Interrupt();
}, Thread.CurrentThread, TaskContinuationOptions.OnlyOnFaulted);
try
{
//do a bunch of tasks here
//want to skip the do while and go to the catch if exception is thrown
do
{
System.Threading.Thread.Sleep(200);
} while (true);
}
catch
{
if (taskException != null)
Console.WriteLine(taskException.Message);
}
}
private static int _loopCounter = 0;
public static void ContinuousTask()
{
int counter = 0;
do
{
if (_loopCounter >= 3)
throw new Exception("error");
if (counter >= 5)
break;
counter += 1;
System.Threading.Thread.Sleep(100);
} while (true);
_loopCounter += 1;
}
}