Tag: 异步

如何处理在一个平台上同步但在另一个平台上异步的代码

在编写基于Xamarin的跨平台C#应用程序时,我经常遇到的情况是在一个平台上同步但在另一个平台上异步的代码。 例如,文件访问在iOS,Android和Mac上是同步的,但在Windows上是异步的。 这导致了一些棘手的问题。 首先,在纯编码级别上,编译器希望方法是异步还是不同步。 但它比这更糟糕。 例如,如果iOS UI线程发现它需要加载一个小文件,并且在UI线程上同步这样做,这可能不会对用户造成任何明显的打嗝。 是的,我意识到,作为一般规则,人们希望预先加载这些资源。 但如果没有发生,并且文件很小,那就不会导致问题。 但是,如果从iOS UI代码调用C#异步方法并等待结果,应用程序将挂起。 结果是我们有两个方法,Foo()和FooAsync(),我们调用哪个方法取决于平台。 但我们不能只让整个事情变得异步。 鉴于此,如何组织一个代码尽可能地坚持DRY,同时在一个平台上保持同步并在另一个平台上保持同步? ** 编辑 – 响应一个例子的请求:这里有一些虚拟代码来说明问题。 如果有人打电话 await StringLoaders.ReadAllText(somePath) 从iOS UI线程,结果是挂起。 是的,这个特定的例子有解决方法。 但一般问题是反复出现的问题。 如果应用程序有很多层,这是特别糟糕的,因为这样做 – 可能需要在整个代码中携带同步/异步区别,从而产生大量方法的两个版本。 public class AsyncStringLoader { public async Task ReadAllTextAsync(string path) { return await Task.Run(() => “Hello”); } } public class StringLoader { public string ReadAllText(string path) { return […]

UploadValuesAsync响应时间

我正在编写测试工具来测试HTTP Post。 测试用例将在10秒间隔内使用webclient类中的UploadValuesAsync发送8个http请求。 它在每8个请求后睡10秒。 我正在记录每个请求的开始时间和结束时间。 当我计算平均响应时间时。 我大约800毫秒。 但是当我在Web客户端中使用UploadValues方法同步运行此测试用例时,我的平均响应时间为250毫秒。 你能告诉我为什么这两种方法有区别吗? 我期待Aync的响应时间减少,但我没有得到。 这是发送8个请求异步的代码 var count = 0; foreach (var nameValueCollection in requestCollections) { count++; NameValueCollection collection = nameValueCollection; PostToURL(collection,uri); if (count % 8 == 0) { Thread.Sleep(TimeSpan.FromSeconds(10)); count = 0; } } UPDATED这是发送8个SYNC请求的代码 public void PostToURLSync(NameValueCollection collection,Uri uri) { var response = new ServiceResponse { Response = […]

在TcpClient BeginConnect之后,应用程序在退出时挂起20秒

我有TcpClient.BeginConnect()和TcpClient.EndConnect()方法的奇怪行为的问题。 我使用BeginConnect()为Connect()方法添加超时(请参阅下面的扩展方法代码)。 如果我连接,我调用EndConnect()并且一切正常,但是如果我超时我不能调用EndConnect(),因为它会阻塞大约20秒,所以我只是调用这个非阻塞代码: result.AsyncWaitHandle.Close(); result.AsyncWaitHandle.Dispose(); client.Close(); 问题是当我在超时后关闭表单(在运行代码之后)我的应用程序将“挂起”大约20秒。 有什么方法可以阻止这种悬挂吗? 这只是在应用程序退出时很不愉快,所以,如果没有其他可能的话,它可能是一些肮脏的杀戮;] 一些说明: 只有在我无法连接到服务器时才会挂起。 退出时,表单将关闭,只有一些进程仍在后台运行。 如果我按下VS2013中的暂停按钮,应用程序挂起,我没有接受任何代码,所以我想这是一些自动创建的线程,其中挂起代码(EndConnect()?)被调用。 当我在超时后等待大约20秒(应用程序响应)然后我关闭表单时没有挂起 – 所以这个阻塞代码(EndConnect()?)会自动从其他一些线程调用。 如果我调用方法TcpClient.Connect()(没有超时)我被阻止大约20秒,但退出时没有挂起。 如果我在超时时运行此非阻塞代码: client.Client.Close(); client.Client.Dispose(); client.Close(); 它仍会在退出时挂起。 即使我将BeginConnect(ip,port,null,null)更改为BeginConnect(ip,port,new AsyncCallback(ConnectCallback),null)并在ConnectCallback中调用客户端上的EndConnect()和Close(),应用程序仍会挂起(ConnectCallback)在退出之前被调用并且其代码没有挂起)。 我写了大约20秒,但它更像是(20 – 超时)秒。 在我的代码II中有超时= 1秒,所以在这种情况下应用程序挂起大约20秒。 以下是我的连接代码: public bool Connect(string localMachineName) { // Get ips for local machine IPAddress[] ips; try { ips = Dns.GetHostEntry(localMachineName).AddressList.Where( o => o.AddressFamily == AddressFamily.InterNetwork).ToArray(); } catch […]

为什么异步ProgressBar上的文本会闪烁?

我想在ProgressBar上显示文本,( 没有 自定义进度条的所有废话)。 这并不难,并且不涉及OnPaint方法 – 如下面代码的button1所示。 但是,此方法会阻止UI线程,这是邪恶的 。 不幸的是,我最好采用异步方法导致文本闪烁,这非常烦人。 有人可以告诉我如何在没有闪烁的情况下异步更新文本吗? (要运行以下代码,只需将其粘贴到包含带有3个按钮和3个ProgressBars的Form的新项目中)。 using System; using System.Drawing; using System.Windows.Forms; using System.Threading.Tasks; using System.Threading; namespace ProgBarTest //change namespace in Program.cs accordingly { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //This method will block the main UI […]

任务 .Result始终为null

我正在研究一些代码来通过Task.Factory.FromAsync(在WP7应用程序中)执行HttpRequest。 任务的Result属性始终为null,但我知道请求本身是正确的,因为如果我将它粘贴到我的浏览器或Fiddler中,它就可以工作。 这是我的代码: string _url = string.Format(“http://requestapi.net/{0}/{1}/{2}”, “objects”,”partitionKey”,”pkey1″); var request = (HttpWebRequest)WebRequest.Create(_url); request.Method = “GET”; Task task1 = Task.Factory.FromAsync( (callback, o) => ((HttpWebRequest)o).BeginGetResponse(callback, o) , result => ((HttpWebRequest)result.AsyncState).EndGetResponse(result) , request); task1.Start(); WebResponse webResponse = task1.Result; string responseString; using (var response = (HttpWebResponse)webResponse) { using (Stream streamResponse = response.GetResponseStream()) { StreamReader reader = new StreamReader(streamResponse); responseString […]

C#等待shell命令在读取异步时返回

我需要从C#应用程序运行外部进程,但在继续执行之前等待它返回。 同时,我需要从stdout获取并更新包含进度信息的文本框。 由于命令可能会运行几分钟并在此期间打印信息,因此显示绝对必要; 但是可能会运行多个命令并且必须按顺序排列,因此等待也是如此。 我试图使用: p = Process.Start(); p.BeginOutputReadLine(); p.WaitForExit(); 但是在等待时冻结了UI线程并阻止了输出的出现。 这个: p.Start(); p.BeginOutputReadLine(); while (!p.HasExited) { Application.DoEvents(); Thread.Sleep(100); } 效果更好,但是完全错误/坏主意并且实际上并没有等待整个期间。 我还简要地尝试使用BackgroundWorker来启动shell进程,但是我不确定如何让UI线程在没有阻塞的情况下等待工作者完成。 我想要做的是提供类似于ShowDialog()的DialogResult ShellExecute(String cmd) ,如果用户允许命令完成,单击取消或命令的返回代码,则返回OK / Cancel(/ fail)结果。 在命令完成(或取消)之前不应返回。 所有shell命令都运行于: ProcessStartInfo info = new ProcessStartInfo { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, FileName = “cmd.exe”, Arguments = “/c […]

Xamarin Forms,使用async来应用ListView ItemSource

我目前正在使用Xamarin Forms,我使用的是从github RESTAPI获得的post方法。 每当我尝试将数据应用到ListView ItemsSource时,我的应用程序崩溃。 以下是当前执行的成功回调,它检索JSON并将其序列化并将其存储在名为listData的列表中。 public class Home : ContentPage { private ListView myListView; private List listInfo = new List { }; RESTAPI rest = new RESTAPI(); Uri address = new Uri(“http://localhost:6222/testBackEnd.aspx”); public Home () { Dictionary data = new Dictionary(); rest.post(address, data, success, null); Content = new StackLayout { Children = { myListView […]

任务列表中空条目的奇怪外观

这是涉及的代码: private static async Task DoRunInOrderAsync(SemaphoreSlim sem, IObservable taskSeedSource, CreateTaskDelegate createTask, OnTaskErrorDelegate onFailed, OnTaskSuccessDelegate onSuccess) where TTaskSeed : class { var tasks = await taskSeedSource .Select(taskSeed => GetPendingOrRunningTask(taskSeed, createTask, onFailed, onSuccess, sem)) .ToList() .ToTask(); await Task.WhenAll(tasks); } private static async Task GetPendingOrRunningTask(T taskSeed, CreateTaskDelegate createTask, OnTaskErrorDelegate onFailed, OnTaskSuccessDelegate onSuccess, SemaphoreSlim sem) where T : class […]

执行进程的C#类中的异步方法

我对这篇文章有一个后续问题。 在我的版本中,我有以下我想要异步。 这是我有的: public virtual Task ExecuteAsync() { var tcs = new TaskCompletionSource(); string exe = Spec.GetExecutablePath(); string args = string.Format(“–input1={0} –input2={1}”, Input1, Input2); try { var process = new Process { EnableRaisingEvents = true, StartInfo = { UseShellExecute = false, FileName = exe, Arguments = args, RedirectStandardOutput = true, RedirectStandardError = true, WorkingDir = […]

C#异步服务器/客户端体系结构

堆叠溢出的第一篇文章! 无论如何……我正在尝试在业余时间自学网络编程,但我已经陷入困境,我无法绕过头脑。 在使用同步网络方法几天后,我决定制作一个客户端/服务器程序,该程序可以: 处理多个并发连接 处理多个通信流 有真正的双向沟通 在更一般的层面上,我想制作一个聊天程序。 多个客户端连接到服务器,可以单独发送和接收数据而没有任何问题……但是服务器也可以将数据从每个客户端发送给其他客户端。 现在我还没有达到目标,所以我在这里寻求一点指导。 我似乎无法使我的循环正常工作,我确信它与代码的异步性质有关……无论出于何种原因,我似乎无法弄清楚什么是错误的。 这是代码块: Server.cs using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; // State object for reading client data asynchronously public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive […]