在.Net 4.5中使用async/await编写多线程方法

12 浏览
0 Comments

在.Net 4.5中使用async/await编写多线程方法

我有一个小问题。\n我承认在.Net 4.5之前,我并没有多次使用多线程,但是有了新的async/await功能后,我决定尝试一下。我开始进行实验,一切看起来都还好,但是我找不到任何关于我的“问题”的解决方案。\n所以每个人都解释了如何在新的.Net平台的转换方法(例如WriteAsync()ReadAsync()等)中使用await,但是如果我想将其用于我自己的方法怎么办?例如,假设我正在执行一项非常昂贵的计算,并希望我的4个核心都能处理它。我可能会有类似于以下的代码:\n

async Task DoLotsOfWork(T[] data, int start, int end)
{
    //执行非常昂贵的操作
}

\n但是由于我没有在那里使用await关键字,该方法只被视为同步方法。我想在外部调用它4次,以便它可以在所有核心上运行,同时向用户显示一些合理的内容(例如“请稍等...”)。我能想到的唯一解决方案是在方法的开头添加await Task.Yield();。就像这样:\n

async Task DoLotsOfWork(T[] data, int start, int end)
{
    await Task.Yield();
    //执行非常昂贵的操作
}

\n在这种情况下,方法的行为符合我的预期。但是是否有更好的解决方案?我觉得应该有比写那行代码更简单/更合理的方法。我知道我可以创建一个Task/Thread对象并调用Start()方法,但这需要更多的工作。我只是认为使用新的async/await功能应该更容易处理这种情况。

0
0 Comments

在使用.Net 4.5中编写多线程方法时,我们可能会遇到一些问题。下面是这个问题出现的原因以及解决方法:

问题的原因:

在这个例子中,我们需要执行一些非常昂贵的工作,但这个工作是同步的。这意味着当我们调用这个方法时,程序会一直阻塞,直到工作完成。这样会导致程序在执行这个工作时变得非常慢。

解决方法:

为了解决这个问题,我们可以使用异步/等待(async/await)关键字来实现多线程编程。下面是具体的解决方法:

首先,我们需要定义一个同步执行非常昂贵工作的方法:

public void DoLotsOfWork(T[] data, int start, int end) 
{
    Thread.Sleep(5000);//placeholder for real work
}

然后,我们可以使用`Task.Run`方法在线程池线程中启动多个实例来执行这个工作:

List tasks = new List();
for(int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() => DoLotsOfWork(data, start, end));
}

接下来,我们可以使用`Task.WhenAll`方法进行非阻塞等待,直到所有工作都完成:

await Task.WhenAll(tasks);

另外,我们还可以使用`Parallel`类来进行并行处理。这个类专门设计用于并行处理,可以自动将工作分割成多个任务,以充分利用可用的处理器核心。但是,这些并行方法会阻塞线程,直到所有任务都完成。所以,如果我们当前处于UI上下文中,不能阻塞线程直到任务完成,我们可以将这些方法包装在`Task.Run`中,以获得一个表示并行工作的`Task`。

// 使用Parallel类进行并行处理
Task.Run(() =>
{
    Parallel.For(0, 10, i =>
    {
        // 执行并行工作
    });
});

如果我们的一个任务返回一个值,我们可以使用`List>`来存储所有任务的结果,并使用`await Task.WhenAll`将结果存储在一个变量中:

List> tasks = new List>();
for(int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() => myFunction()));
}
T[] results = await Task.WhenAll(tasks);

通过使用异步/等待关键字和任务并行处理,我们可以提高程序的性能和响应能力,使得程序能够更好地利用多核处理器的能力。

0