我试图在webservice方法中做一些异步的东西.假设我有以下API调用:http://www.example.com/api.asmx
并且该方法称为GetProducts().
我这个GetProducts方法,我做了一些事情(例如从数据库中获取数据)然后在我返回结果之前,我想做一些异步的东西(例如给我发电子邮件).
所以这就是我所做的.
[WebMethod(Description = "Bal blah blah.")]
public IList<Product> GetProducts()
{
// Blah blah blah ..
// Get data from DB .. hi DB!
// var myData = .......
// Moar clbuttic blahs :) (yes, google for clbuttic if you don't know what that is)
// Ok .. now send me an email for no particular reason, but to prove that async stuff works.
var myObject = new MyObject();
myObject.SendDataAsync();
// Ok, now …Run Code Online (Sandbox Code Playgroud) 我有一个ac #windows form app我一起扔了.这很简单:
输入:
该应用程序搜索源文件夹中的文本文件以查找输入的文本字符串; 如果找到该字符串,则将该文件和具有相同名称的图像文件复制到目标文件夹.它会根据整数输入多次执行此操作.
所以我有一个按钮,在按钮点击事件中我打电话
ProcessImages(tbDID.Text, tbSource.Text, tbDest.Text, comboBoxNumberImages.SelectedItem.ToString());
Run Code Online (Sandbox Code Playgroud)
这是:
private void ProcessImages(string DID, string SourceFolder, string DestFolder, string strNumImages)
{
int ImageCounter = 0;
int MaxImages = Convert.ToInt32(strNumImages);
DirectoryInfo di = new DirectoryInfo(SourceFolder);
foreach (FileInfo fi in di.GetFiles("*.txt"))
{
if (fi.OpenText().ReadToEnd().Contains(DID))
{
//found one!
FileInfo fi2 = new FileInfo(fi.FullName.Replace(".txt", ".tif"));
if (fi2.Exists)
{
try
{
tbOutput.Text += "Copying " + fi2.FullName + " to " + tbDest.Text + "\r\n";
fi2.CopyTo(tbDest.Text + @"\" …Run Code Online (Sandbox Code Playgroud) 我希望我的OSX应用程序位于后台并等待键盘快捷键才能生效.它应该可以配置为类似于首选项中的Growl,或者可以作为状态栏中的dropbox访问.
我的问题很多.从我看到.NET 4.5,我印象非常深刻.不幸的是我的所有项目都是.NET 4.0,我不考虑迁移.所以我想简化我的代码.
目前,我的大多数代码通常需要足够的时间来冻结屏幕,我会执行以下操作:
BackgroundWorker bd = new BackgroundWorker();
bd.DoWork += (a, r) =>
{
r.Result = ProcessMethod(r.Argument);
};
bd.RunWorkerCompleted += (a, r) =>
{
UpdateView(r.Result);
};
bd.RunWorkerAsync(args);
Run Code Online (Sandbox Code Playgroud)
老实说,我已经厌倦了.当存在逻辑复杂的用户交互时,这成为一个大问题.
我想知道,如何简化这种逻辑?(请记住,我在.Net 4.0)我注意到谷歌的一些事情,但没有找到任何易于实施和适合我的需求.
我认为这个解决方案如下:
var foo = args as Foo;
var result = AsyncHelper.CustomInvoke<Foo>(ProcessMethod, foo);
UpdateView(result);
public static class AsyncHelper
{
public static T CustomInvoke<T>(Func<T, T> func, T param) where T : class
{
T result = null;
DispatcherFrame frame = new DispatcherFrame();
Task.Factory.StartNew(() =>
{
result = func(param);
frame.Continue = false; …Run Code Online (Sandbox Code Playgroud) wpf design-patterns pattern-matching backgroundworker task-parallel-library
在我的.NET C#项目中,我使用"BackgroundWorker"来调用另一个类中的方法.以下是我的主要表格的源代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
testClass t1 = new testClass();
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
t1.changevalue(1000);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
label1.Text += Convert.ToString(e.ProgressPercentage);
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
并在我的项目中名为"testClass.cs"的单独类文件中包含以下代码.我想从此类向BackgroundWorker报告进度,以便我能够从label1显示main中的进度.
class testClass
{
private int val;
public int changevalue(int i)
{
for (int j = 0; j < 1000; j++)
{
val += i + j;
//from here i need …Run Code Online (Sandbox Code Playgroud) 我正在使用BackGroundWorker类在sqlserver中插入一些值.我在这里循环插入值.我正在使用以下代码
public void bw_Convert_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = e.Argument;
for (int i = 0; i < fTable.Rows.Count; i++)
{
try
{
SqlCommand cmd = new SqlCommand("INSERT INTO TBL_CDR_ANALYZER (LNG_UPLOAD_ID, DAT_START, LNG_DURATION, INT_DIRECTION, INT_CALL_DATA_TYPE, \n" +
"TXT_TARGET_NUMBER, TXT_OTHER_PARTY_NUMBER, TXT_TARGET_IMSI, TXT_TARGET_IMEI, TXT_TARGET_CELL_ID, TXT_ROAMING_NETWORK_COMPANY_NAME) VALUES \n" +
"(@UPLOAD_ID, @START_DATE, @DURATION, @DIRECTION, @CALL_TYPE, @TARGET_NUMBER, @OTHER_PARTY_NUMBER, @IMSI, @IMEI, @CELL_ID, @ROAMING_NAME)", sqlCon);
cmd.Parameters.Add("@UPLOAD_ID", SqlDbType.Int).Value = 1;
cmd.Parameters.Add("@START_DATE", SqlDbType.DateTime).Value = fTable.Rows[i]["CallDate"];
cmd.Parameters.Add("@DURATION", SqlDbType.Int).Value = fTable.Rows[i]["CallDuration"];
cmd.Parameters.Add("@DIRECTION", SqlDbType.Int).Value = GetCallDirection(fTable.Rows[i]["CallDirection"].ToString());
cmd.Parameters.Add("@CALL_TYPE", SqlDbType.Int).Value = GetCallType(fTable.Rows[i]["CallType"].ToString());
cmd.Parameters.Add("@TARGET_NUMBER", SqlDbType.VarChar, …Run Code Online (Sandbox Code Playgroud) 如果我在后面的代码中的函数中,并且我想在状态栏中实现显示"正在加载...",则以下内容是有意义的,但正如我们从WinForms中知道的那样是NoNo:
StatusBarMessageText.Text = "Loading Configuration Settings...";
LoadSettingsGridData();
StatusBarMessageText.Text = "Done";
Run Code Online (Sandbox Code Playgroud)
我们现在从WinForms第1章101类开始,在整个函数完成之前,表单不会显示对用户的更改...意味着"加载"消息将永远不会显示给用户.需要以下代码.
Form1.SuspendLayout();
StatusBarMessageText.Text = "Loading Configuration Settings...";
Form1.ResumeLayout();
LoadSettingsGridData();
Form1.SuspendLayout();
StatusBarMessageText.Text = "Done";
Form1.ResumeLayout();
Run Code Online (Sandbox Code Playgroud)
在WPF中处理这个基本问题的最佳做法是什么?
后台工作线程是否重复使用?
具体来说,如果我在后台工作程序的DoWork()方法中设置了一个命名数据槽(线程局部存储),那么该数据槽的值是否会持续存在,以后可能会发现某个其他线程?
我不会这么想,但我有这个错误......
编辑:这篇博客文章表明BackGroundWorker使用ThreadPool,这意味着线程被重用.所以问题就变成了; 重用线程是否可能在调用之间持久保存线程本地存储?
简单来说:
我通过调用取消我的操作CancelAsync()上BackgroundWorker的方法,当执行落入事件RunWorkerCompleted,性质Cancelled上RunWorkerCompletedEventArgs是错误的.我无法弄清楚何时何地应该将其设置为true,因为这是一个EventArgs属性.
谁能给我一点帮助?此外,抱歉,如果它是重复,但我找不到任何有关此问题.
为了将数据传递到BackgroundWorker的DoWork我使用一个单独的包装类"实例:
MyParams mpar = new MyParams();
...
mpar.Par1 = par1val;
mpar.Par2 = par2val;
mpar.Par3 = par3val;
...
var worker1 = new System.ComponentModel.BackgroundWorker();
worker1.DoWork += new DoWorkEventHandler(worker1_DoWork);
worker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker1_RunWorkerCompleted);
worker1.RunWorkerAsync(mpar);
Run Code Online (Sandbox Code Playgroud)
然后我可以使用mpar实例的参数worker1_DoWork,在另一个线程中操作.
void worker1_DoWork(object sender, DoWorkEventArgs e)
{
//here we use mpar.Par1, mpar.Par2 and so on
}
Run Code Online (Sandbox Code Playgroud)
在RunWorkerCompletedEventHandler我们做的UI线程一些postactions.
我的问题是:我们可以在RunWorkerCompleted处理程序中使用它在处理程序mpar之前工作的实例,DoWork我们可以确定它的值与它的相同DoWork吗?如果不是,那么为各个BackgroundWorker操作阶段共享参数的正确方法是什么?
void worker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Dispatcher.BeginInvoke((Action)(() =>
{
//Can …Run Code Online (Sandbox Code Playgroud) backgroundworker ×10
c# ×8
.net ×3
wpf ×2
asp.net ×1
events ×1
macos ×1
parameters ×1
thread-local ×1
winforms ×1