这是我第一次在多线程应用程序上工作(一般来说,不仅仅是用C#),因此我只知道关于它的简单概念。我基本上实现了System.Threading
命名空间。
我有一个字典,它将对象A与它的ID(Dictionary<int,A>
)联系起来。每个A都要做一个操作(每个A都有相同的操作),我希望这个操作在一个单独的线程列表中工作,每个A一个。
我知道System.Threading
是实现多线程的糟糕方法,但我现在只知道一点这个命名空间。我做了一些东西:
public class ThreadManager
{
private Dictionary<int, A> _aList;
public Dictionary<int, A> AList
{
get { return _aList; }
set { _aList = value; }
}
private Dictionary<int, Thread> _threadList;
public Dictionary<int, Thread> ThreadList
{
get { return _threadList; }
set { _threadList = value; }
}
public ThreadManager(Dictionary<int, A> list)
{
AList = list;
ThreadList = new Dictionary<int, Thread>();
foreach (A a in AList)
{
int id = a.Id;
ThreadList.Add(id, new Thread(new ParameterizedThreadStart(Operation)));
}
}
public void Operation(object data)
{
try
{
/*** do something***/
}
catch (Exception e)
{
/*** throw exception ***/
}
}
}
字符串
当我运行特定的线程在我的应用程序代码点:
ThreadManager.ThreadList[i].Start(data)
型
做需要的操作似乎工作得很好。但是,我认为这个解决方案真的很丑,功能也不是很好。
此外,还有一个大问题。当异常在throw中时,正如预期的那样,它不是catch out of thread。我可以在代码的另一个点捕获线程异常吗?它工作在不同的线程上(例如主线程)。
编辑:
为了明确,我想没有线程阻塞主线程。我需要能够在主线程上操作,而操作工作。
1条答案
按热度按时间hgc7kmma1#
我的建议是使用
Task.Run
和Parallel.ForEach
的组合:字符串
1.使用
async
和await
关键字允许您编写不阻塞UI线程的异步代码,与编写正常同步代码的方式相同。当异步操作正在进行时,UI保持响应。Task.Run
将action
委托的处理卸载到ThreadPool
线程。ThreadPool
是由.NET基础结构管理的可重用线程池。如果需要,您可以使用ThreadPool.SetMinThreads
方法对其进行微调。Parallel.ForEach
在多个ThreadPool
线程上并行调用body
委托,强制执行MaxDegreeOfParallelism
策略。如果您想要无限并行,请使用MaxDegreeOfParallelism = -1
配置它。在异常的情况下,
Parallel.ForEach
将停止调用body
委托,并将在所有当前运行的调用完成时完成。所有错误调用的错误将被捆绑在AggregateException
中。此异常将首先由Task.Run
传播,然后由await
操作符传播,您可以在UI线程上使用Click
事件处理程序中的try
/catch
块来处理它。(省略catch
块),在这种情况下,它将被处理为通用的Application.ThreadException
事件处理程序。如果你也省略了这个,WinForms应用程序默认显示的默认错误弹出窗口将通知用户,并为用户提供继续或退出应用程序的选项。