我再一次重新研究了异步任务.无论我如何设置任务,我的应用程序一直受到UI冻结的影响.我有以下代码从网页下载字符串:
internal string DownloadString(string URL)
{
var result = LoadCompanyContracts(URL);
return result.Result;
}
internal async Task<string> LoadCompanyContracts(string URL)
{
Task<string> task2 = Task<string>.Factory.StartNew(() =>
{
for (int i = 0; i <= 10000000; i++) Console.WriteLine(i);
WebClient wc = new WebClient();
string tmp = wc.DownloadString(new Uri(URL));
return tmp;
});
return task2.Result;
}
Run Code Online (Sandbox Code Playgroud)
当我执行此任务时,在for循环期间,我的应用程序的UI正在冻结.即使我相信这段代码不应该冻结UI我也无法找到解决方案.我尝试了很多不同的选项,并且真的想使用任务而不是使用webclient异步的线程或事件.
信息:我正在为我的项目使用.net 4.5.我的代码的不同之处在于这些函数在类库中(不知道它是否重要).
是否可以通过从我的代码中调用DownloadString函数来运行此代码而不用异步await阻止用户界面?如果不是什么替代品(任何好的nuget包)?
我需要使用3个任务创建一个foreach循环,这需要等到所有3个任务完成后再移动到下一个任务.就像是
foreach (class r in sets)
{
Task.Factory.StartNew(() => {
DoThisFunction1();
}, TaskCreationOptions.LongRunning);
Task.Factory.StartNew(() => {
DoThisFunction2();
}, TaskCreationOptions.LongRunning);
Task.Factory.StartNew(() => {
DoThisFunction3();
}, TaskCreationOptions.LongRunning);
}
Run Code Online (Sandbox Code Playgroud)
有人可以给出一个简单的方法如何做到这一点?
我理解WebClient有一个DownloadStringAsync可以使用的方法
var result = await client.DownloadStringAsync(url);
Run Code Online (Sandbox Code Playgroud)
而且我想知道那只是做的有什么不同
var result = await new Task<string>(() => client.DownloadString(url));
Run Code Online (Sandbox Code Playgroud) 我正在尝试包装HttpListener该类并添加更多处理Web套接字的逻辑.
最后,我试图将GetContextAsync()方法包装为仅返回HttpListenerContext作为Web套接字的对象.
到目前为止,我有:
public Task<HttpListenerContext> GetContextAsync()
{
Task<HttpListenerContext> contextTask = listener.GetContextAsync();
if (contextTask.Result.Request.IsWebSocketRequest)
{
return contextTask;
}
else
{
contextTask.Result.Response.StatusCode = 500;
contextTask.Result.Response.Close();
return GetContextAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我调用外部函数(包装类)时,使用:
HttpListenerContext listenerContext = await listener.GetContextAsync();
Run Code Online (Sandbox Code Playgroud)
在await实现第一次连接之前,不会返回主线程.
如果它对某人有帮助,我最终会采取以下措施:
public async Task<HttpListenerContext> GetContextAsync()
{
HttpListenerContext listenerContext = await listener.GetContextAsync();
while (!listenerContext.Request.IsWebSocketRequest)
{
listenerContext.Response.StatusCode = 500;
listenerContext.Response.Close();
listenerContext = await listener.GetContextAsync();
}
return listenerContext;
}
Run Code Online (Sandbox Code Playgroud) using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TaskStart
{
class Program
{
private static void PrintMessage()
{
Console.WriteLine("Hello Task library!");
}
static void Main(string[] args)
{
//method 1
//Task.Factory.StartNew(() => { Console.WriteLine("Hello Task library!");});
//method 2
//Task task = new Task(new Action(PrintMessage));
//task.Start();
//method3
Task task = new Task(delegate { PrintMessage(); });
task.Start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想让我的控制台应用程序打印消息Hello Task library!.我目前正在使用method 3下面.出于某种原因,Press any key to continue当我按下Ctrl + F5VS2015 时,应用程序显示一个空白屏幕,并显示消息.
为什么我的信息没有打印出来.
我有一段C#代码(它在Xamarin应用程序中,但我不认为这是相关的)初始化我的应用程序.它是这样的:
class AppController {
public override void InitializeApp() {
// Do stuff to initialize services & database
checkNeedsUpdates();
}
void checkNeedsUpdates() {
Task.Run(() => {
string json = API.Call("versions").Result
// It never gets here
});
}
}
class API {
HttpClient client;
public Task<string> Call(string endpoint) {
// Setup headers and access token things before handing over to POST function
return Post(/*params*/);
}
public async Task<string> Post(/*params*/) {
// Setup
return await Request(/*params*/);
}
public async Task<string> Request(/*params*/) {
HttpRequestMessage …Run Code Online (Sandbox Code Playgroud) 我试图更好地理解C#中的任务和异步操作,我已经运行了这个示例程序,但我对输出感到困惑.当我运行它时,程序有时不会在CallMethod中输出Console输出
int length = await task
Run Code Online (Sandbox Code Playgroud)
有时确实如此,但当我取消注释时
Console.ReadLine()
Run Code Online (Sandbox Code Playgroud)
它总是运行所有的CallMethod.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace Tasks1
{
class Program
{
static void Main(string[] args)
{
Task task = new Task(CallMethod);
task.Start();
task.Wait();
//Console.ReadLine();
}
static async void CallMethod()
{
string filePath = "/Users/testname/Projects/Tasks1/Tasks1/Sample.txt";
Task<int> task = ReadFile(filePath);
Console.WriteLine("Other Work 1");
Console.WriteLine("Other Work 2");
Console.WriteLine("Other Work 3");
int length = await task;
Console.WriteLine(" Total Length: " + length);
Console.WriteLine("After work 1");
Console.WriteLine("After work 2");
}
static async Task<int> …Run Code Online (Sandbox Code Playgroud) 怎么了 以及如何解决?我正在尝试学习c#-task中的新主题。当我运行时,我收到错误消息:
Error CS0407 'Task MainWindow.btn1_ClickAsync(object, RoutedEventArgs)' has the wrong return type
public async Task btn1_ClickAsync(object sender, RoutedEventArgs e)
{
txtState.Text = "btn1_Click started";
await LongRunningFunc1();
txtState.Text = "btn1_Click finished";
}
private async Task LongRunningFunc1()
{
txt1.Text = "Processing 1 .....";
btn1.Content = "Wait";
await Task.Delay(5000);
txt1.Text = "Hello From Func1";
btn1.Content = "Click";
}
Run Code Online (Sandbox Code Playgroud)
WPF设计师:
<Grid>
<TextBlock Name="txtState" Margin="265,10,274,356"/>
<TextBlock Name="txt1" Height="50" RenderTransformOrigin="0.966,-0.95" Margin="281,68,320,301"/>
<TextBlock Name="txt2" Height="50" Margin="253,238,274,131" />
<Button Name="btn1" Background="Red" Margin="281,127,300,208" Click="btn1_ClickAsync"></Button>
<Button Name="btn2" Background="Aqua" Margin="298,309,311,27"></Button>
</Grid>
Run Code Online (Sandbox Code Playgroud) 我正在实现一个方法,以便相互下载多个文件.
我希望Method是异步的,所以我不会阻止UI.
这是下载单个文件的方法,并将Download-Task返回到上级方法,后者下载所有文件(进一步向下).
public Task DownloadFromRepo(String fileName)
{
// Aktuellen DateiNamen anzeigen, fileName publishing for Binding
CurrentFile = fileName;
// Einen vollqualifizierten Pfad erstellen, gets the path to the file in AppData/TestSoftware/
String curFilePath = FileSystem.GetAppDataFilePath(fileName);
// Wenn die Datei auf dem Rechner liegt, wird sie vorher gelöscht / Deletes the file on the hdd
FileSystem.CleanFile(fileName);
using (WebClient FileClient = new WebClient())
{
FileClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler((s, e) =>
{
Progress++;
});
// Wenn der Download abgeschlossen ist.
FileClient.DownloadFileCompleted += …Run Code Online (Sandbox Code Playgroud) 我有一个接受int输入和返回的方法Task<Dictionary<DateTime, HistPrice>>
public static async Task<Dictionary<DateTime, HistPrice>> GetPrices(int seriesId) {
...
return Dictionary<DateTime, HistPrice>;
}
Run Code Online (Sandbox Code Playgroud)
现在我想并行调用上面的方法来获取值1,2,3,4,5,6,7,8的列表.
List<int> seriesIdDist = new List<int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 });
var tasks = new List<Task>();
foreach(var t in seriesIdDist) {
tasks.Add(GetPrices(t));
}
await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)
直到这里一切正常,问题在于从任务中提取结果.我试着像提取结果一样
foreach(var ta in tasks) {
var res = await ta;//error in this line
}
Run Code Online (Sandbox Code Playgroud)
但它说
CS0815无法为隐式类型变量赋值void
我在这里错过了什么?
c# ×10
task ×10
asynchronous ×6
async-await ×5
.net ×2
wpf ×2
foreach ×1
loops ×1
methods ×1
webclient ×1